游戏介绍:
这里直接拿百度知道的说明 https://zhidao.baidu.com/question/1994394486771253027.html
2048游戏共有16个格子,初始时会有两个格子上安放了两个数字2,每次可以选择上下左右其中一个方向去滑动,每滑动一次,所有的数字方块都会往滑动的方向靠拢外,系统也会在空白的地方随即出现一个数字方块,相同数字的方块在靠拢、相撞时会相加。系统给予的数字方块不是2就是4,玩家要想办法在这小小的16格范围中凑出“2048”这个数字方块。
游戏分析:
4个操作基本都是一致的,这里我们就只拿向左(按键a)举例:
给定一个4*4的列表,
首先,将所有的大于0的数向该行的左边移动,用一个循环,先用切片切取一行(一列),然后对这行进行一个向左挪移,把不是0的数字左移,后面补0,保证长度为4,然后把这个得到的列表重新给到原来的列表,这样原来的列表就全部按照行靠左排列了。
第二步是将向左排列的列表,取每行,然后每行进行判断,如果相邻的单位相等,就把两个数相加,保存在左边的单元格里面,然后这2个数后面的数全部左移,末尾补0来保证长度为4,循环往复(实际不会有多少次的,一行最多2次相加),这样就得到了一个运算后的列表了。
以上是4个按键的响应和处理事件的思路实现。
然后还需要对操作的合法性进行判断,第一个是16个元素都大于0,而且向左(是指按键a或者其他按键对应的方向)的时候,第一列的4个元素和第二列相邻的都没有相等的,同时第二列与第三列,第三列与第四列都没有,这样的话,向左操作就是不合法的了,输出提示信息告诉玩家不能向左移动了。同理可得其他3个按键的操作判断依据。
游戏结束标志:
1,16个元素中有一个达到了2048就恭喜玩家,然后提示是否继续,如果继续,就保存一个标签,后面不要每次操作就提示是否继续,这样带来的游戏体验就会贼差,所以通过判断该标签就可以了。
2,16个元素,没有任何相邻的元素是相等的,那么游戏无法在任何方向进行移动了,游戏也就结束了,这样玩家挑战2048失败。
该游戏是在终端进行的,终端的输入都是需要按回车之后才执行的,所以这样肯定影响体验的,所以需要响应玩家的键盘输入,这里引入了pygame库,可以直接进行按键的捕获,event.type == KEYDOWN代表着按键按下了,进行响应的逻辑处理,event.type == KEYUP代表按键释放了,释放的时候打印4*4单元格的信息。
至此,整个游戏就完成了,可以在终端直接运行该游戏了。博主在终端试玩了一下,目前没有发现逻辑问题,但是遇到了一个小问题,在一段长时间没有任何操作的情况下,再输入a之后,终端没有响应了,这个只能留待后续对pygame库更清楚之后解决了。
游戏缺省的部分是取最大值,保存到文件中,然后在游戏结束的时候,读取文件中的值,与当前结果最大值进行比较,进行响应的提示。
源码:
"""
this game is 2048
"""
import random
import sys,random,time,pygame
from pygame.locals import *
pygame.init()
screen = pygame.display.set_mode((6,5))
random_list = [2,2,2,2,2,4]
def add_random_number(lst):
"""random a number from random_list to 4*4 list if the position is 0"""
while True:
random_index = random.randint(0,15)
if lst[random_index] == 0:
random_number = random.choice(random_list)
lst[random_index] = random_number
break
else:
continue
def deal_add_left(lst):
"""
give a ordered list to left,
this func do add number cal,return list
4 4 * *
2 2 2 *
2 2 2 *
8 4 * *
----->
8 * * *
4 2 * *
4 2 * *
8 4 * *
"""
for i in range(4):
l = lst[i*4:i*4+4]
l = func_left(l)
lst[i*4:i*4+4] = l
def move_to_left(lst):
"""
give a 4*4 list,return 4 rows number ,every row move to left
and then return 4*4 list
"""
for i in range(4):
l = lst[i*4:i*4+4]
l = return_lst_left(l)
lst[i*4:i*4+4] = l
return lst
def deal_add_right(lst):
"""the same as deal_add_left(lst),
but this func deal with right operate"""
for i in range(4):
l = lst[i*4:i*4+4]
l = func_right(l)
lst[i*4:i*4+4] = l
return lst
def move_to_right(lst):
"""4*4 list ,all rows move to right"""
for i in range(4):
l = lst[i*4:i*4+4]
l = return_lst_right(l)
lst[i*4:i*4+4] = l
return lst
def func_left(lst):
"""[2,4,4,2] union the nearly same element to left-> [2,8,2,0]"""
for i in range(3):
if lst[i] == lst[i+1] and lst[i] != 0:
lst[i] = lst[i] << 1
lst[i+1:4] = lst[i+2:4] + [0]
return lst
def func_right(lst):
"""[2,4,4,2] union the nearly same element to left-> [0,2,8,2]"""
for i in range(3,0,-1):
if lst[i] == lst[i-1] and lst[i] != 0 and lst[i-1] != 0:
lst[i] = lst[i] << 1
lst[0:i] = [0]+lst[0:i-1]
return lst
def deal_add_top(lst):
"""get 4 column from 4*4 list,then do func_left for every column"""
for i in range(4):
l = lst[i:16:4]
l = func_left(l)
lst[i:16:4] = l
return lst
def return_lst_left(lst):
"""give a list(4 number),return a list which all number left ordered if it > 0
[2,0,4,4] ---->[2,4,4,0]"""
l = []
for x in lst:
if x > 0:
l.append(x)
l += [0,0,0,0]
l = l[0:4]
return l
def move_to_top(lst):
"""the same as move_to_left"""
for i in range(4):
l = lst[i:16:4]
l = return_lst_left(l)
lst[i:16:4] = l
return lst
def deal_add_buttom(lst):
"""the same as move_to_right"""
for i in range(4):
l = lst[i:16:4]
l = func_right(l)
lst[i:16:4] = l
return lst
def return_lst_right(lst):
"""give a list(4 number),return a list which all number right ordered if it > 0
[2,0,4,4] ---->[0,2,4,4]"""
l = []
while len(lst) > 0:
x = lst.pop()
if x > 0:
l.append(x)
l += [0,0,0,0]
l = l[0:4]
l.reverse()
return l
def move_to_buttom(lst):
"""the same as move_to_right"""
for i in range(4):
l = lst[i:16:4]
l = return_lst_right(l)
lst[i:16:4] = l
return lst
def print_result(lst):
"""print result as following:
4 2 * *
4 * * *
4 * * *
8 2 * 2
"""
for i in range(4):
for j in range(4):
if lst[i*4+j] == 0:
print("%6s"%"*",end="")
else:
print("%6d"%lst[i*4+j],end="")
print()
print()
def action_a(number_list_test):
deal_add_left(move_to_left(number_list_test))
def action_d(number_list_test):
deal_add_right(move_to_right(number_list_test))
def action_w(number_list_test):
deal_add_top(move_to_top(number_list_test))
def action_s(number_list_test):
deal_add_buttom(move_to_buttom(number_list_test))
def deal_error_op_s_w(number_list_test):
"""key_s or key_w pressed,judge whether can operate"""
count = 0 #count number of a element >0 in a list
for x in number_list_test:
if x > 0:
count += 1
if count == 16: #all element > 0
cal = 0 #if nearly element is not equal,cal+1;
#if cal ==12,it stand for no element is equal with it's nearby element
for i in range(3):
for j in range(4):
#compare by row,row 1 compare with row 2
if number_list_test[i*4+j] == number_list_test[(i+1)*4+j]:
return False
else:
cal += 1
if cal == 12:
return True
else:
return False
def deal_error_op_a_d(number_list_test):
"""key_a or key_d pressed,judge whether can operate"""
count = 0
for x in number_list_test:
if x > 0:
count += 1
if count == 16:
cal = 0
for i in range(4):
for j in range(3):
#compare by column,column 1 compare with column 2
if number_list_test[i*4+j] == number_list_test[i*4+j+1]:
return False
else:
cal += 1
if cal == 12:
return True
else:
return False
def win_game(number_list_test):
"""if one element >= 2048,player win"""
for x in number_list_test:
if x >= 2048:
print("Congratulation on your perfect preformance!")
return True
return False
def main1():
pygame.init()
screen = pygame.display.set_mode((1,1))
number_list_test = [
0,4,0,2,
2,0,2,0,
0,2,2,0,
8,0,0,2,
]
# random.shuffle(number_list_test)
print_result(number_list_test)
tag = False#if player reach 2048,save the choice of continue or not
while True:
if deal_error_op_s_w(number_list_test) == True and deal_error_op_a_d(number_list_test) == True:
print("Game over!")
exit()
else:
for event in pygame.event.get():
if event.type ==KEYDOWN:
keys = pygame.key.get_pressed()
if keys[97]:#a
if deal_error_op_a_d(number_list_test) == False:
action_a(number_list_test)
add_random_number(number_list_test)
# print_result(number_list_test)
else:
print("cant move to left")
elif keys[115]:#s
if deal_error_op_s_w(number_list_test) == False:
action_s(number_list_test)
add_random_number(number_list_test)
# print_result(number_list_test)
else:
print("can't move to buttom")
elif keys[119]:#w
if deal_error_op_s_w(number_list_test) == False:
action_w(number_list_test)
add_random_number(number_list_test)
# print_result(number_list_test)
else:
print("can't move to top")
elif keys[100]:#d
if deal_error_op_a_d(number_list_test) == False:
action_d(number_list_test)
add_random_number(number_list_test)
# print_result(number_list_test)
else:
print("can't move to right")
elif keys[112]: #q
#to add move action if needed
pass
else:
exit()
elif event.type == KEYUP:
print_result(number_list_test)
if tag == False:
win = win_game(number_list_test)
if win:
next = input("continue or not,press y/Y to continue")
if next == 'y' or next == 'Y':
tag = True
continue
else:
exit()
if __name__ == "__main__":
main1()
注明:该游戏也是昨天看同桌rao-j-j开发了2048,然后我拿他的手机试玩了一下之后才开发的,之前根本不知道这个游戏怎么玩的。不完善的地方后续修补了。