admin 管理员组

文章数量: 1087677

2048游戏—源码

#!/usr/bin/env python3
# -*- coding:utf-8 -*-
# 作者:魏明泽
# 参考网址:  random
import math__mataclass__ = type  # 使用新式类# 此类为地图模块封装的类
class map2048():# 重新设置游戏数据def reset(self):self.__row = 4  # 行数self.__col = 4  # 列数self.data = [[0 for x in range(self.__col)]for y in range(self.__row)]# self.data = [[x + 4 * y for x in range(self.__col)]#              for y in range(self.__row)]# self.data = [[0,0,0,0],[0,0,0,0],[0,0,0,0],[0,0,0,0]]self.fill2()self.fill2()def __init__(self):self.reset()# 获取没有数字的位置的个数def get_space_count(self):"""获取没有数字的方格的数量"""count = 0for r in self.data:count += r.count(0)return count# 获取游戏的得数。def get_score(self):s = 0for r in self.data:for c in r:s += 0 if c < 4 else c * int((math.log(c, 2) - 1.0))return s# 填充2到空位置,如果填度成功返回True,如果已满,则返回False,def fill2(self):blank_count = self.get_space_count()if 0 == blank_count:return False# 生成随机位置pos = random.randrange(0, blank_count)offset = 0for r in self.data:for ci in range(self.__col):if 0 == r[ci]:if offset == pos:r[ci] = 2return Trueoffset += 1# 判断游戏是否结束def is_gameover(self):for r in self.data:# 如果水平方向还有0,则游戏没有结束if r.count(0):return False# 水平方向如果有两个相邻的元素相同,则没有游戏结束for i in range(self.__col - 1):if r[i] == r[i + 1]:return Falsefor c in range(self.__col - 1):# 竖直方向如果有两个相邻的元素相同,则没有游戏结束for r in range(self.__row - 1):if self.data[r][c] == self.data[r + 1][c]:return False# 以上都没有,则游戏结束return True# 2048游戏的左移动 (采用"贾琳倩"美女老师的方法进行移动)def left(self):# moveflag 是否成功移动数字标志位,如果有移动则为真值,原地图不变则为假值moveflag = False# 将所有数字向左移动来填补左侧空格for times in range(self.__col - 1):for r in self.data:for c in range(self.__col - 1):if 0 == r[c]:moveflag = Truer[c] = r[c + 1]r[c + 1] = 0# 判断是否发生碰幢,如果有碰撞则合并,合并结果靠左,右则填充空格for r in self.data:for c in range(self.__col - 1):if r[c] == r[c + 1]:moveflag = Truer[c] *= 2r[c + 1] = 0# 再将所有数字向左移动来填补左侧空格for times in range(self.__col - 1):for r in self.data:for c in range(self.__col - 1):if 0 == r[c]:moveflag = Truer[c] = r[c + 1]r[c + 1] = 0return moveflag# 游戏右移操作def right(self):for r in self.data:r.reverse()moveflag = self.left()for r in self.data:r.reverse()return moveflag# 游戏上移操作def up(self):# moveflag 是否成功移动数字标志位,如果有移动则为真值,原地图不变则为假值moveflag = False# 将所有数字向上移动来填补上面空格for times in range(self.__row - 1):for c in range(self.__col):for r in range(self.__row - 1):if 0 == self.data[r][c]:moveflag = Trueself.data[r][c] = self.data[r + 1][c]self.data[r + 1][c] = 0# 判断是否发生碰幢,如果有碰撞则合并,合并结果靠上,下面填充空格for c in range(self.__col):for r in range(self.__row - 1):if self.data[r][c] == self.data[r + 1][c]:moveflag = Trueself.data[r][c] *= 2self.data[r + 1][c] = 0# 再将所有数字向上移动来填补上面空格for times in range(self.__row - 1):for c in range(self.__col):for r in range(self.__row - 1):if 0 == self.data[r][c]:moveflag = Trueself.data[r][c] = self.data[r + 1][c]self.data[r + 1][c] = 0return moveflag# 游戏下移操作def down(self):self.data.reverse()moveflag = self.up()self.data.reverse()return moveflagimport sysif (sys.version_info > (3, 0)):from tkinter import *from tkinter import messagebox
else:from Tkinter import *game = map2048()keymap = {'a': game.left,'d': game.right,'w': game.up,'s': game.down,'Left': game.left,'Right': game.right,'Up': game.up,'Down': game.down,'q': exit,
}game_bg_color = "#bbada0"
mapcolor = {0: ("#cdc1b4", "#776e65"),2: ("#eee4da", "#776e65"),4: ("#ede0c8", "#f9f6f2"),8: ("#f2b179", "#f9f6f2"),16: ("#f59563", "#f9f6f2"),32: ("#f67c5f", "#f9f6f2"),64: ("#f65e3b", "#f9f6f2"),128: ("#edcf72", "#f9f6f2"),256: ("#edcc61", "#f9f6f2"),512: ("#e4c02a", "#f9f6f2"),1024: ("#e2ba13", "#f9f6f2"),2048: ("#ecc400", "#f9f6f2"),4096: ("#ae84a8", "#f9f6f2"),8192: ("#b06ca8", "#f9f6f2"),
}# 游戏各方块的lable数据
map_labels = []# 鼠标按下处理函数
def on_mouse_down(event):print("clicked at", event.x, event.y)# 键盘按下处理函数
def on_key_down(event):keysym = event.keysymif keysym in keymap:if keymap[keysym]():game.fill2()update_ui()if game.is_gameover():mb = messagebox.askyesno(title="gameover", message="游戏结束!\n是否退出游戏!")if mb:exit()else:game.reset()update_ui()# 刷新界面函数
def update_ui():# 更改各个Label的设置for r in range(len(game.data)):for c in range(len(game.data[0])):number = game.data[r][c]label = map_labels[r][c]label['text'] = str(number) if number else ''label['bg'] = mapcolor[number][0]label['foreground'] = mapcolor[number][1]label_score['text'] = str(game.get_score())# 以下为2048的界面
root = Tk()
root.title('2048')
# root.iconbitmap('./favicon.ico')  # 48x48 ico bitmapframe = Frame(root, width=300, height=300, bg=game_bg_color)
frame.grid(sticky=N+E+W+S)
# 按键事件见:
# 设置焦点能接收按键事件
frame.focus_set()
frame.bind("<Key>", on_key_down)
# 以下绑定鼠标按下事件
# frame.bind("<Button-1>", on_mouse_down)
# 以下绑定鼠标移动事件
# frame.bind("<Motion>", on_mouse_down)
# 以下绑定鼠标抬起事件
frame.bind("<ButtonRelease-1>", on_mouse_down)
# 见 : 初始化图形界面
for r in range(len(game.data)):row = []for c in range(len(game.data[0])):value = game.data[r][c]text = '' if 0 == value else str(value)label = Label(frame, text=text, width=4, height=2,font=("黑体", 30, "bold"))label.grid(row=r, column=c, padx=5, pady=5, sticky=N+E+W+S)row.append(label)map_labels.append(row)
bottom_row = len(game.data)
print("button", str(bottom_row))
label = Label(frame, text='分数', font=("黑体", 30, "bold"),bg="#bbada0", fg="#eee4da")
label.grid(row=bottom_row, column=0, padx=5, pady=5)
label_score = Label(frame, text='0', font=("黑体", 30, "bold"),bg="#bbada0", fg="#ffffff")
label_score.grid(row=bottom_row, columnspan=2, column=1, padx=5, pady=5)def reset_game():game.reset()update_ui()# restart_button = Button(frame, text='重新开始', command=reset_game)
restart_button = Button(frame, text='重新开始', font=("黑体", 16, "bold"),# width=4, height=2,bg="#8f7a66", fg="#f9f6f2", command=reset_game)
restart_button.grid(row=bottom_row, column=3, padx=5, pady=5)update_ui()root.mainloop()

 

本文标签: 2048游戏源码