当前位置:   article > 正文

用220行python代码实现2048小游戏(源码和详细注释以及分析)_2048python代码

2048python代码

- 刚刚在实验楼学习了2048小游戏,用下午和晚上的时间看懂代码加注释,现在把自己的理解和遇到的问题做一下总结,希望对大家有帮助。

实验链接:

https://www.shiyanlou.com/courses/368

首先2048游戏的玩法大家肯定都很了解:初始界面是一个二维矩阵,然后有两个数字(2或4),经过自己的上下左右移动,不相邻的数字紧挨到一起,相邻数字如果相同就合并为一个,然后继续随机产生2或4,经过这样的合并,数字不断变大,最终得到2048获得游戏胜利。
详细的原理可以去实验楼看实验步骤,最有用的就是这张图。这个游戏总共就是有有限的几个状态:初始化,游戏, 游戏胜利,游戏结束,退出游戏。这非常适合用有限状态机来解决。在这里插入图片描述
  • 简单说一下整体逻辑(main函数):初始化界面,等待用户动作,用户产生动作后,进入对应函数,产生相应的效果。举个例子:游戏初始运行init,进入game,用户按下w键,进入move函数,产生向上的移动,同时合并数字和随机产生数字;当数字到达胜利条件,执win函数,界面显示胜利。
  • 主要运行流程(能力有限,尽量看吧):

在这里插入图片描述

下面将详细注释的完整代码贴下:

#-*- coding:utf-8 -*-

import curses  #一种很丰富的库,看到啥学啥
from random import randrange, choice # generate and place new tile   #choice 返回一个随机值,randrange 返回一个规定的数
from collections import defaultdict  #默认字典的设置
#from itertools import chain 
#ascll值列表
letter_codes = [ord(ch) for ch in 'WASDRQwasdrq']  #不区分大小写情况,全部包容,ord()返回字符的十进制整数
actions = ['Up', 'Left', 'Down', 'Right', 'Restart', 'Exit']#几个按键动作
actions_dict = dict(zip(letter_codes, actions * 2)) #将动作和ascll值打包成元组对

def get_user_action(keyboard):  
    """得到用户的响应动作"""
    char = "N"
	#没有动作时一直等待
    while char not in actions_dict:    
        char = keyboard.getch()
		#返回响应的按键
    return actions_dict[char]

def transpose(field):
    """矩阵转置"""
    return [list(row) for row in zip(*field)]

def invert(field):
    """矩阵逆转"""
    return [row[::-1] for row in field]

class GameField(object):
    """游戏场景"""
    def __init__(self, height=4, width=4, win=2048):
        """初始化游戏窗口"""
        self.height = height
        self.width = width
        self.win_value = win
        self.score = 0
        self.highscore = 0
        self.reset()

    def reset(self):
        """重置游戏"""
		#记录最高分
        if self.score > self.highscore:
            self.highscore = self.score
		#分数清零
        self.score = 0
		#遍历游戏区域,给整个区域全部赋值0
        self.field = [[0 for i in range(self.width)] for j in range(self.height)]
		#生成2或者4
        self.spawn()
        self.spawn()

    def move(self, direction):
        """移动时候的变化"""
        def move_row_left(row):
            def tighten(row): # squeese non-zero elements together
                """将行中的非零部分补足为0"""
				#不是0的数
                new_row = [i for i in row if i != 0]
				#准换列表  比如  4 0 0 2  转换成4 2 0 0
                new_row += [0 for i in range(len(row) - len(new_row))]
                return new_row
			#row是一个列表
            def merge(row):
                """数字合并"""
                pair = False
                new_row = []
                for i in range(len(row)):
                    if pair:
						#这个位置数字变为原来2倍
                        new_row.append(2 * row[i])
						#记录得分值
                        self.score += 2 * row[i]
                        pair = False
                    else:
						#判断临近的值是否相同
                        if i + 1 < len(row) and row[i] == row[i + 1]:
                            pair = True
                            new_row.append(0)
                        else:
                            new_row.append(row[i])
                assert len(new_row) == len(row)
                return new_row
            return tighten(merge(tighten(row)))

        moves = {
   }
		#四种移动情况全部包含
        moves['Left']  = lambda field:                              \
                [move_row_left(row) for row in field]
        moves['Right'] = lambda field:                              \
                invert(moves['Left'](invert(field)))
        moves['Up']    = lambda field:                              \
                transpose(moves['Left'](transpose(field)))  #将向上转成向左来看,哦同时对应的区域的数字也要转到左边来
        moves['Down']  = lambda field:                              \
                transpose(moves['Right'](transpose(field)))

        if direction in moves:
            
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
本文内容由网友自发贡献,转载请注明出处:https://www.wpsshop.cn/w/Monodyee/article/detail/174723
推荐阅读
相关标签
  

闽ICP备14008679号