




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)
文檔簡介
第利用JS實現(xiàn)AI自動玩貪吃蛇目錄演示技術(shù)棧源碼樣式設置構(gòu)建食物對象構(gòu)建貪吃蛇對象構(gòu)建自動貪吃
演示
自動貪吃蛇
技術(shù)棧
bottom屬性規(guī)定元素的底部邊緣。該屬性定義了定位元素下外邊距邊界與其包含塊下邊界之間的偏移。
注釋:如果position屬性的值為static,那么設置bottom屬性不會產(chǎn)生任何效果。
對于static元素,為auto;對于長度值,則為相應的絕對長度;對于百分比數(shù)值,為指定值;否則為auto。
對于相對定義元素,如果bottom和top都是auto,其計算值則都是0;如果其中之一為auto,則取另一個值的相反數(shù);如果二者都不是auto,bottom將取top值的相反數(shù)。
默認值:auto繼承性:no版本:CSS2JavaScript語法:object.style.bottom=50px
user-select屬性規(guī)定是否能選取元素的文本。
在web瀏覽器中,如果您在文本上雙擊,文本會被選取或高亮顯示。此屬性用于阻止這種行為。
user-select:auto|none|text|all;
auto默認。如果瀏覽器允許,則可以選擇文本。none防止文本選取。text文本可被用戶選取。all單擊選取文本,而不是雙擊。
源碼
樣式設置
canvas{
position:absolute;
width:100vh;
height:100vh;
margin:auto;
top:0;
bottom:0;
left:0;
right:0;
user-select:none;
background:#000;
cursor:pointer;
構(gòu)建食物對象
varfood={
x:0,
y:0,
//addrandomfood
add:functionadd(){
varemptyNodes=[];
for(varx=0;xmap.width;++x){
for(vary=0;ymap.height;++y){
if(!map.collision(x,y))emptyNodes.push({
x:x,
y:y
if(emptyNodes.length){
varp=emptyNodes[Math.floor(Math.random()*emptyNodes.length)];
this.x=p.x;
this.y=p.y;
構(gòu)建貪吃蛇對象
varsnake={
body:[],
head:{
x:0,
y:0
removeTail:functionremoveTail(){
varp=this.body.shift();
map.setSnake(p.x,p.y,0);
addHead:functionaddHead(x,y){
this.head.x=x;
this.head.y=y;
this.body.push({
x:x,
y:y
map.setSnake(x,y,1);
move:functionmove(dir){
varnext=map.getNext(this.head.x,this.head.y,dir);
this.addHead(next.x,next.y);
if(next.x===food.xnext.y===food.y){
food.add();
}elsethis.removeTail();
//snakeIA
nextDirection:functionnextDirection(){
varx=this.head.x;
vary=this.head.y;
varpathNumber=map.tour(x,y);
vardistanceToFood=map.distance(pathNumber,map.tour(food.x,food.y));
vardistanceToTail=map.distance(pathNumber,map.tour(snake.body[0].x,snake.body[0].y));
varcuttingAmountAvailable=distanceToTail-4;
varnumEmptySquaresOnBoard=map.size-snake.body.length-1;
if(distanceToFooddistanceToTail)cuttingAmountAvailable-=1;
varcuttingAmountDesired=distanceToFood;
if(cuttingAmountDesiredcuttingAmountAvailable)cuttingAmountAvailable=cuttingAmountDesired;
if(cuttingAmountAvailable0)cuttingAmountAvailable=0;
varcanGoRight=!map.collision(x+1,y);
varcanGoLeft=!map.collision(x-1,y);
varcanGoDown=!map.collision(x,y+1);
varcanGoUp=!map.collision(x,y-1);
varbestDir=-1;
varbestDist=-1;
vardist=0;
if(canGoRight){
dist=map.distance(pathNumber,map.tour(x+1,y));
if(dist=cuttingAmountAvailabledistbestDist){
bestDir=map.Right;
bestDist=dist;
if(canGoLeft){
dist=map.distance(pathNumber,map.tour(x-1,y));
if(dist=cuttingAmountAvailabledistbestDist){
bestDir=map.Left;
bestDist=dist;
if(canGoDown){
dist=map.distance(pathNumber,map.tour(x,y+1));
if(dist=cuttingAmountAvailabledistbestDist){
bestDir=map.Down;
bestDist=dist;
if(canGoUp){
dist=map.distance(pathNumber,map.tour(x,y-1));
if(dist=cuttingAmountAvailabledistbestDist){
bestDir=map.Up;
bestDist=dist;
if(bestDist=0)returnbestDir;
if(canGoUp)returnmap.Up;
if(canGoLeft)returnmap.Left;
if(canGoDown)returnmap.Down;
if(canGoRight)returnmap.Right;
returnmap.Right;
構(gòu)建自動貪吃
varmap={
//initmap
init:functioninit(width,height){
var_this=this;
this.width=width;
this.height=height;
this.size=width*height;
this.scale=Math.min(canvasWidth,canvasHeight)/Math.max(this.width,this.height);
//HamiltonianCycle
//flags
var_array2D=this.array2D(width,height,true);
var_array2D2=_slicedToArray(_array2D,2);
this.tour=_array2D2[0];
this.setTour=_array2D2[1];
var_array2D3=this.array2D(width/2,height/2);
var_array2D4=_slicedToArray(_array2D3,2);
this.isVisited=_array2D4[0];
this.setVisited=_array2D4[1];
var_array2D5=this.array2D(width/2,height/2);
var_array2D6=_slicedToArray(_array2D5,2);
this.canGoRight=_array2D6[0];
this.setGoRight=_array2D6[1];
var_array2D7=this.array2D(width/2,height/2);
var_array2D8=_slicedToArray(_array2D7,2);
this.canGoDown=_array2D8[0];
this.setGoDown=_array2D8[1];
var_array2D9=this.array2D(width,height);
var_array2D10=_slicedToArray(_array2D9,2);
this.isSnake=_array2D10[0];
this.setSnake=_array2D10[1];
this.canGoLeft=function(x,y){
if(x===0)returnfalse;
return_this.canGoRight(x-1,y);
this.canGoUp=function(x,y){
if(y===0)returnfalse;
return_this.canGoDown(x,y-1);
//directions
Left:1,
Up:2,
Right:3,
Down:4,
//flat2Darray
array2D:functionarray2D(width,height,protect){
vardata=newUint16Array(width*height);
return[function(x,y){
returndata[x+width*y];
},protectfunction(x,y,value){
vari=x+width*y;
if(!data[i])data[i]=value;
}:function(x,y,value){
data[x+width*y]=value;
//testsnakecollision
collision:functioncollision(x,y){
if(x0||x=this.width)returntrue;
if(y0||y=this.height)returntrue;
returnthis.isSnake(x,y)!==0;
//pathdistance
distance:functiondistance(a,b){
if(ab)returnb-a-1;elsereturnb-a-1+this.size;
//HamiltonianCycle
generate_r:functiongenerate_r(fromx,fromy,x,y){
if(x0||y0||x=this.width/2||y=this.height/2)return;
if(this.isVisited(x,y))return;
this.setVisited(x,y,1);
if(fromx!==-1){
if(fromxx)this.setGoRight(fromx,fromy,1);elseif(fromxx)this.setGoRight(x,y,1);elseif(fromyy)this.setGoDown(fromx,fromy,1);elseif(fromyy)this.setGoDown(x,y,1);
for(vari=0;ii++){
varr=Math.floor(Math.random()*4);
switch(r){
case0:
this.generate_r(x,y,x-1,y);
break;
case1:
this.generate_r(x,y,x+1,y);
break;
case2:
this.generate_r(x,y,x,y-1);
break;
case3:
this.generate_r(x,y,x,y+1);
break;
this.generate_r(x,y,x-1,y);
this.generate_r(x,y,x+1,y);
this.generate_r(x,y,x,y+1);
this.generate_r(x,y,x,y-1);
//findnextdirectionincycle
findNextDir:functionfindNextDir(x,y,dir){
if(dir===this.Right){
if(this.canGoUp(x,y))returnthis.Up;
if(this.canGoRight(x,y))returnthis.Right;
if(this.canGoDown(x,y))returnthis.Down;
returnthis.Left;
}elseif(dir===this.Down){
if(this.canGoRight(x,y))returnthis.Right;
if(this.canGoDown(x,y))returnthis.Down;
if(this.canGoLeft(x,y))returnthis.Left;
returnthis.Up;
}elseif(dir===this.Left){
if(this.canGoDown(x,y))returnthis.Down;
if(this.canGoLeft(x,y))returnthis.Left;
if(this.canGoUp(x,y))returnthis.Up;
returnthis.Right;
}elseif(dir===this.Up){
if(this.canGoLeft(x,y))returnthis.Left;
if(this.canGoUp(x,y))returnthis.Up;
if(this.canGoRight(x,y))returnthis.Right;
returnthis.Down;
return-1;//Unreachable
//generateHamiltonianCycle
generateTourNumber:functiongenerateTourNumber(){
varx=0;
vary=0;
vardir=this.canGoDown(x,y)this.Up:this.Left;
varnumber=0;
do{
varnextDir=this.findNextDir(x,y,dir);
switch(dir){
casethis.Right:
this.setTour(x*2,y*2,number++);
if(nextDir===dir||nextDir===this.Down||nextDir===this.Left)this.setTour(x*2+1,y*2,number++);
if(nextDir===this.Down||nextDir===this.Left)this.setTour(x*2+1,y*2+1,number++);
if(nextDir===this.Left)this.setTour(x*2,y*2+1,number++);
break;
casethis.Down:
this.setTour(x*2+1,y*2,number++);
if(nextDir===dir||nextDir===this.Left||nextDir===this.Up)this.setTour(x*2+1,y*2+1,number++);
if(nextDir===this.Left||nextDir===this.Up)this.setTour(x*2,y*2+1,number++);
if(nextDir===this.Up)this.setTour(x*2,y*2,number++);
break;
casethis.Left:
this.setTour(x*2+1,y*2+1,number++);
if(nextDir===dir||nextDir===this.Up||nextDir===this.Right)this.setTour(x*2,y*2+1,number++);
if(nextDir===this.Up||nextDir===this.Right)this.setTour(x*2,y*2,number++);
if(nextDir===this.Right)this.setTour(x*2+1,y*2,number++);
break;
casethis.Up:
this.setTour(x*2,y*2+1,number++);
if(nextDir===dir||nextDir===this.Right||nextDir===this.Down)this.setTour(x*2,y*2,number++);
if(nextDir===this.Right||nextDir===this.Down)this.setTour(x*2+1,y*2,number++);
if(nextDir===this.Down)this.setTour(x*2+1,y*2+1,number++);
break;
dir=nextDir;
switch(nextDir){
casethis.Right:
++x;
break;
casethis.Left:
--x;
break;
casethis.Down:
++y;
break;
casethis.Up:
--y;
break;
}while(number!==this.size);
//getnextnode
getNext:functiongetNext(x,y,dir){
switch(dir){
casethis.Left:
if(x)return{
x:x-1,
y:y
break;
casethis.Up:
if(y)return{
x:x,
y:y-1
break;
casethis.Right:
return{
x:x+1,
y:y
break;
casethis.Down:
return{
x:x,
y:y+1
break;
return{
x
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
- 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025養(yǎng)殖戶生豬買賣合同書
- 保安亭建設合同范例
- 保安績效工資合同范例
- 中介購房押金合同范例
- 上海住宅翻新裝修合同范例
- 中途合伙協(xié)議合同范例
- 保溫杯定制合同范例
- 六險一金合同范例
- 不平等合同范例
- 2025-2030年中國二乙基乙醇胺行業(yè)市場現(xiàn)狀供需分析及投資評估規(guī)劃分析研究報告
- (二模)貴陽市2025年高三年級適應性考試(二)物理試卷(含答案)
- 合資公司成立可行性研究報告范文
- 2025年中國電子產(chǎn)品租賃行業(yè)市場占有率及投資前景預測分析報告
- 2025年中國亮白防蛀固齒牙膏市場調(diào)查研究報告
- 上甘嶺戰(zhàn)役課件
- 黑龍江省齊齊哈爾市普高聯(lián)誼校2022-2023學年高一下學期語文期末試卷(含答案)
- 名家班主任培訓:AI賦能與德育創(chuàng)新
- 工程師評審代辦合同協(xié)議
- 心力衰竭試題及答案
- 公安治安管理培訓
- 湖北省武漢市2025屆高中畢業(yè)生四月調(diào)研考試物理試題及答案(武漢四調(diào))
評論
0/150
提交評論