python学习----2048小游戏

#coding:utf-8
import 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.fill2()
        self.fill2()
    def __init__(self):
        self.reset()
    def get_space_count(self):
        count = 0
        for r in self.data:
            count += r.count(0)
        return count
    def get_score(self):
        s = 0
        for r in self.data:
            for c in r:
                s += 0 if c < 4 else c * int((math.log(c, 2) - 1.0))
        return s
    def fill2(self):
        blank_count=self.get_space_count()
        if 0 == blank_count:
            return False
        pos = random.randrange(0, blank_count)
        offset = 0
        for r in self.data:
            for ci in range(self.__col):
                if 0 == r[ci]:
                    if offset == pos:
                        r[ci] = 2
                        return True
                    offset += 1
    def is_gameover(self):
        for r in self.data:
            if r.count(0):
                return False#水平上还有空格则没有结束
            for i in range(self.__col - 1):
                if r[i] == r[i + 1]:
                    return False#水平方向还有可以合并的数字则游戏没有结束
        for 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#没有以上的条件则游戏结束
    def left(self):#左移动
        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 = True
                        r[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 = True
                    r[c] *= 2
                    r[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 = True
                        r[c] = r[c + 1]
                        r[c + 1] = 0
        return 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=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 = True
                        self.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 = True
                    self.data[r][c] *= 2
                    self.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 = True
                        self.data[r][c] = self.data[r + 1][c]
                        self.data[r + 1][c] = 0
        return moveflag
    def down(self):#向下移动
         self.data.reverse()
         moveflag = self.up()
         self.data.reverse()
         return moveflag
import sys
if (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: ("#FF3366","#CC0066"), 2: ("#FFCCFF","#CC0066"), 4: ("#FF99FF","#FF33CC"), 8: ("#FF6699","#FF33CC"), 16: ("#FF33FF","#FF00FF"), 32: ("#FF66FF","#FF00FF"),
          64: ("#FF00CC","#FF3399"),128: ("#993366","#FF3399"),256:("#CC0066","#FF3366"), 512: ("#FF33CC","#FF3366"), 1024: ("#FF00FF","#FF33FF"),
          2048: ("#FF00FF","#FF33FF"), 4096: ("#FF3399","#FF00CC")}#数字颜色和方块的颜色
map_labels = []
def on_mouse_down(event):
    print("clicked at",event.x,event.y)
def on_key_down(event):
    keysym = event.keysym
    if 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():
    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())
root=Tk()#图像化界面的显示
root.title('2048')
frame = 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("<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"), bg="#8f7a66", fg="#f9f6f2", command=reset_game)
restart_button.grid(row=bottom_row,column=3,padx=5,pady=5)
update_ui()
root.mainloop()

效果如下:在这里插入图片描述

  • 6
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 10
    评论
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值