2048小游戏后端的实现

本文介绍2048游戏后端算法设计,包括利用栈进行方块移动和融合、通过BFS判断游戏状态及新方块产生的算法实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

游戏的由来

 2048小游戏是首先在github上发布的一款开源的小游戏, 游戏的规则十分简单, 但也意外的获得了世界上很多人的青睐。在这里, 我想介绍一下我实现2048小游戏后端的一些小算法的设计。

A.栈的使用

 在2048的游戏当中, 最主要的操作便是上下左右的操作, 而这里, 我们需要使用一个常用的数据结构--栈。在移动方块的时候, 相同数字的方块会在移动的过程中融合。这和栈只允许栈顶作操作的特点十分吻合。所以, 首先需要实现的是一个栈(当然大部分语言的标准库内都有这样的内容, 详情看下面的代码)

B.新方块的产生

  在2048当中, 在每一次的移动之后后端需要做两项操作, 首先是判断游戏是否可以通过移动来产生方块的融合, 其次则是找到一个任意的空位来产生一个新的方块。
  首先是判断游戏是否结束。在这里我们可以采用BFS的方法, 对每个方块进行尽量的广度搜索, 从而找到可以融合的地方。其次是找到一个任意的空位。我们将空位的x,y坐标都用线性表储存起来, 然后对这个线性表执行一次洗牌操作, 就可以任意找到一个空白的位置来插入一个新的方块了, 这样大致2048游戏的后端就完成了。

下面是实现的代码:
首先是线性栈, 因为无聊所以写了一个:

#the stack module is designed for the movement of 
#puzzle.

class Stack:
    def __init__(self):
        #the base is the element list
        self.__base =[]
        #the number of the element in the stack
        self.length =0
        #the top points to the top element of the stack
        self.__top =0

    #the insert function is for element insertion
    def insert(self, n):
        self.__base.append(n)
        self.length +=1
        self.__top  +=1
        #change the lenght and the top pointers

    #to pop the head element in the stack
    def pop(self):
        if self.__top >0:
            self.__base.pop(self.__top-1)
            self.length -=1
            self.__top -=1

    #return the head element in the stack
    def front(self):
        if(self.__top >0):
           return self.__base[self.__top-1]
        else: return 0

下面是主要操作的实现:

import random
from stack import *

class puzzle:
    #create the puzzle of the game of a given size
    def __init__(self, n):
        self.__board =[]
        for i in range(n):
            self.__board.append(n*[0])

        self.__size =n
        #set the initial size and board

    #find a proper position to insert the element
    def creatInsertLocation(self):
        #use a list to decide the location of insertion
        stack =[]
        for i in range(self.__size):
            for j in range(self.__size):
                if(self.__board[i][j]==0):stack.append([i,j])

        #decide which number to insert
        x =random.randint(1,2)
        if(len(stack)>0):
            random.shuffle(stack)
            z =stack[0][0] 
            y =stack[0][1]
            self.__board[z][y] =2**x
            return True
        else:
            return False

    #This function aims to print the whole board
    def showBoard(self):
        print self.__board

    #this method is designed for judge the game can go on
    def moveable(self):
        flag =False   #to record if the puzzle is moveable
        mvx =[1,-1,0,0]
        mvy =[0,0,1,-1]
        for i in range(self.__size):
            for j in range(self.__size):
                for k in range(4):
                    mx =i+mvx[k]
                    my =j+mvy[k]
                    #if the index is out of range, then continue
                    if(mx<0 or mx>=self.__size or my <0 or my >=self.__size):
                        continue
                    #if we find a movable position, then the whole puzzle is movable
                    if(self.__board[i][j] ==self.__board[mx][my]):
                        flag =True
                        break
                if(flag):break;
            if(flag):break;
        return flag

    #this function defines the up move
    def upMove(self):
       for i in range(self.__size):
           s =Stack()
           for j in range(self.__size):
               if(self.__board[j][i] ==0):continue
               elif self.__board[j][i] ==s.front():
                   s.pop()
                   s.insert(2*self.__board[j][i])
               elif self.__board[j][i] !=s.front():
                   s.insert(self.__board[j][i])
               self.__board[j][i] =0
           for j in range(s.length-1, -1, -1):
               self.__board[j][i] =s.front()
               s.pop()

    #this function is designed for the puzzle down move
    def downMove(self):

       for i in range(self.__size):
           s =Stack()
           for j in range(self.__size -1, -1, -1):
               if(self.__board[j][i] ==0):continue
               elif self.__board[j][i] ==s.front():
                   s.pop()
                   s.insert(2*self.__board[j][i])
               elif self.__board[j][i] !=s.front():
                   s.insert(self.__board[j][i])
               self.__board[j][i] =0
           for j in range(s.length, 0, -1):
               self.__board[self.__size -j][i] =s.front()
               s.pop()


    #this function is designed for the left move of the puzzle
    def leftMove(self):
       for i in range(self.__size):
           s =Stack()
           for j in range(self.__size):
               if(self.__board[i][j] ==0):continue
               elif self.__board[i][j] ==s.front():
                   s.pop()
                   s.insert(2*self.__board[i][j])
               elif self.__board[i][j] !=s.front():
                   s.insert(self.__board[i][j])
               self.__board[i][j] =0
           for j in range(s.length -1, -1, -1):
               self.__board[i][j] =s.front()
               s.pop()

    #this function is designed for the right move of the puzzle
    def rightMove(self):
       for i in range(self.__size):
           s =Stack()
           for j in range(self.__size-1, -1, -1):
               if(self.__board[i][j] ==0):continue
               elif self.__board[i][j] ==s.front():
                   s.pop()
                   s.insert(2*self.__board[i][j])
               elif self.__board[i][j] !=s.front():
                   s.insert(self.__board[i][j])
               self.__board[i][j] =0
           for j in range(s.length, 0, -1):
               self.__board[i][self.__size -j] =s.front()
               s.pop()

    def getElem(self,i, j):
        return self.__board[i][j]

结语

十分遗憾的是, 由于本人的前端设计实在太渣, 所以没有实现相应的前端。在此如果有实现前端设计的同道中人欢迎将代码发送到我的邮箱wyc8094@gmail.com 谢谢!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值