|
楼主 |
发表于 7-15-2025 18:05:57
|
显示全部楼层
- import random,pygame,sys,time
- def copy(board):return [row[:] for row in board] #copies a board
- def maxnum(board):return max(max(row) for row in board) #finds the max number in a board
- def rr(board):return [list(row) for row in zip(*board[::-1])] #rotates a board clockwise
- def flp(board):return [[board[j][i] for j in range(len(board))] for i in range(len(board[0]))] #flips a board diagonally
- def score(board):return sum(3**(x-2) for row in board for x in row if x>2) #scores a board
-
- def up(board): #moves a board upwards
- nBoard=copy(board)
- moved=[0,0,0,0] #moved columns
- for y in range(4): #iterates all 4 columns
- for x in range(3): #iterates from 1st row to the 3rd row
- if nBoard[x][y]==0 and nBoard[x+1][y]!=0: #an empty block with a non-empty neighbor block below it
- moved[y]=1
- nBoard[x][y]=nBoard[x+1][y]
- elif nBoard[x][y]==1 and nBoard[x+1][y]==2 or nBoard[x][y]==2 and nBoard[x+1][y]==1: #merge 1 and 2
- moved[y]=1
- nBoard[x][y]=3
- elif nBoard[x][y]==nBoard[x+1][y] and nBoard[x][y]>=3: #merge same numbers
- moved[y]=1
- nBoard[x][y]+=1
- if moved[y]==1: #move numbers below
- for i in range(x+1,3):
- nBoard[i][y]=nBoard[i+1][y]
- nBoard[3][y]=0
- break
- return nBoard,moved
- def down(board):
- nBoard,moved=up(rr(rr(board)))
- return rr(rr(nBoard)),moved[::-1]
- def left(board):
- nBoard,moved=up(rr(board))
- return rr(rr(rr(nBoard))),moved[::-1]
- def right(board):
- nBoard,moved=up(rr(rr(rr(board))))
- return rr(nBoard),moved
- def next(board,moved):
- if sum(moved)==0:
- return nNum
- ones=sum(row.count(1) for row in board)
- twos=sum(row.count(2) for row in board)
- if twos-ones>=4: #no twos if already many twos
- weights=[20,0,10,1]
- elif ones-twos>=4: #no ones if already many ones
- weights=[0,20,10,1]
- else:
- weights=[10+2*(twos-ones),10+2*(ones-twos),10,1] #weight also floats depending on current ones and twos
- n=random.choices([1,2,3,4],weights=weights,k=1)[0]
- if n!=4:
- return n
- m=maxnum(Board)
- mid=random.randint(5,m-4)
- return mid
- def insert(board,moved,nNum,dir):
- if sum(moved)==0: #unable to insert
- return board
- if nNum>=5:
- nNum=random.choice([nNum-1,nNum,nNum+1])
- nBoard=copy(board)
- i=random.choices([0,1,2,3],weights=moved,k=1)[0] #choses a moved row or column to insert
- if dir==0:
- nBoard[3][i]=nNum
- if dir==1:
- nBoard[0][i]=nNum
- if dir==2:
- nBoard[i][3]=nNum
- if dir==3:
- nBoard[i][0]=nNum
- return nBoard
- def draw(scr):
- scr.fill((235,235,235))
- pygame.draw.line(scr,(23,23,23),(10,10),(410,10))
- pygame.draw.line(scr,(23,23,23),(10,160),(410,160))
- pygame.draw.line(scr,(23,23,23),(10,310),(410,310))
- pygame.draw.line(scr,(23,23,23),(10,460),(410,460))
- pygame.draw.line(scr,(23,23,23),(10,610),(410,610))
- pygame.draw.line(scr,(23,23,23),(10,10),(10,610))
- pygame.draw.line(scr,(23,23,23),(110,10),(110,610))
- pygame.draw.line(scr,(23,23,23),(210,10),(210,610))
- pygame.draw.line(scr,(23,23,23),(310,10),(310,610))
- pygame.draw.line(scr,(23,23,23),(410,10),(410,610)) #draws the grids
- for x in range(4):
- for y in range(4):
- num=Board[x][y] #draws tiles
- if num==0:
- color2=(220,220,220)
- pygame.draw.rect(scr,color2,(100*y+20,150*x+20,80,130))
- continue
- if num>2:
- color1=(23,23,23)
- color2=(242,242,242)
- pygame.draw.rect(scr,color2,(100*y+20,150*x+20,80,130))
- num=3*2**(num-3)
- if num==1:
- color1=(255,235,235)
- color2=(23,180,255)
- pygame.draw.rect(scr,color2,(100*y+20,150*x+20,80,130))
- if num==2:
- color1=(235,255,255)
- color2=(255,90,135)
- pygame.draw.rect(scr,color2,(100*y+20,150*x+20,80,130))
- d=len(str(num))
- if d==1:
- s=50
- if d==2 or d==3:
- s=40
- if d==4:
- s=32
- if d>=5:
- s=26
- font=pygame.font.SysFont('Monaco',s)
- img=font.render(str(num),True,color1,color2)
- img_rect=img.get_rect()
- img_rect.center=(60+100*y,85+150*x)
- scr.blit(img,img_rect)
- font=pygame.font.SysFont('Monaco',45)
- img=font.render('Next Num',True,(23,23,23),(235,235,235))
- img_rect=img.get_rect()
- img_rect.center=(580,80)
- scr.blit(img,img_rect)
- if nNum<=3:
- font=pygame.font.SysFont('Monaco',50)
- color=(23,23,23)
- if nNum==1:
- color=(40,40,192)
- if nNum==2:
- color=(192,40,40)
- img=font.render(str(nNum),True,color,(235,235,235))
- img_rect=img.get_rect()
- img_rect.center=(580,170)
- scr.blit(img,img_rect)
- if nNum>=5: #here 5 stands for 6,12,24, 8 stands for 48,96,192, etc.
- color=(23,23,23)
- n=3*2**(nNum-4)
- font=pygame.font.SysFont('Monaco',50-8*(n>100))
- img=font.render(str(n),True,color,(235,235,235))
- img_rect=img.get_rect()
- img_rect.center=(490,170)
- scr.blit(img,img_rect)
- n=3*2**(nNum-3)
- font=pygame.font.SysFont('Monaco',50-8*(n>100))
- img=font.render(str(n),True,color,(235,235,235))
- img_rect=img.get_rect()
- img_rect.center=(580,170)
- scr.blit(img,img_rect)
- n=3*2**(nNum-2)
- font=pygame.font.SysFont('Monaco',50-8*(n>100))
- img=font.render(str(n),True,color,(235,235,235))
- img_rect=img.get_rect()
- img_rect.center=(670,170)
- scr.blit(img,img_rect)
- font=pygame.font.SysFont('Monaco',45)
- img=font.render('Score',True,(23,23,23),(235,235,235))
- img_rect=img.get_rect()
- img_rect.center=(580,250)
- scr.blit(img,img_rect)
- img=font.render(str(score(Board)),True,(23,23,23),(235,235,235)) #draws the score
- img_rect=img.get_rect()
- img_rect.center=(580,340)
- scr.blit(img,img_rect)
- pygame.display.update()
- Board=[[0,0,1,1],
- [2,3,0,2],
- [0,0,3,0],
- [1,1,0,9]] #initial board
- moved=[1,1,1,1]
- nNum=next(Board,moved)
- pygame.init()
- screen=pygame.display.set_mode((800,620))
- pygame.display.set_caption('Threes!'*random.choice([1,3]))
- draw(screen)
- while True:
- for event in pygame.event.get():
- if event.type==pygame.QUIT:
- pygame.quit()
- sys.exit()
- elif event.type==pygame.KEYDOWN:
- if event.key==pygame.K_UP:
- Board,moved=up(Board)
- Board=insert(Board,moved,nNum,0)
- elif event.key==pygame.K_DOWN:
- Board,moved=down(Board)
- Board=insert(Board,moved,nNum,1)
- elif event.key==pygame.K_LEFT:
- Board,moved=left(Board)
- Board=insert(Board,moved,nNum,2)
- elif event.key==pygame.K_RIGHT:
- Board,moved=right(Board)
- Board=insert(Board,moved,nNum,3)
- elif event.key==pygame.K_BACKSPACE: #resets game
- Board=[[0,0,1,1],
- [2,3,0,2],
- [0,0,3,0],
- [1,1,0,9]]
- moved=[1,1,1,1]
- nNum=next(Board,moved)
- draw(screen)
- else:
- continue
- nNum=next(Board,moved)
- draw(screen)
复制代码 |
|