当前位置:   article > 正文

1000行Python代码实现俄罗斯方块/扫雷/五子棋/贪吃蛇_python小游戏编程100例1000行源码

python小游戏编程100例1000行源码

Python开发小游戏,它有又双叒叕来了…

一、效果展示

1、俄罗斯方块

在这里插入图片描述

这个应该是玩起来最最简单的了…

2、扫雷

在这里插入图片描述

运气好,点了四下都没踩雷哈哈…

3、五子棋

在这里插入图片描述

我是菜鸡,玩不赢电脑人…

4、贪吃蛇

在这里插入图片描述

有需要更多Python学习方法或者各种办公奇淫巧技的同学请看文末哦!!
我已经我为大家准备了一份针对零基础的Python学习资料,有兴趣的同学可以看看哦。
  • 1
  • 2

害,这个是最惊心动魄的,为了我的小心脏,不玩了不玩了…

女朋友:你就是借机在玩游戏,逮到了
在这里插入图片描述
在这里插入图片描述
啊这…

那我不吹牛逼了,我们来敲代码吧~

在这里插入图片描述

二、代码展示

1、俄罗斯方块

方块部分

这部分代码单独保存py文件,这里我命名为 blocks.py

方块形状的设计,一开始我是做成 4 × 4,长宽最长都是4的话旋转的时候就不考虑怎么转了,就是从一个图形替换成另一个。

要实现这个功能,只要固定左上角的坐标就可以了。

import random
from collections import namedtuple

Point \= namedtuple('Point', 'X Y')
Shape \= namedtuple('Shape', 'X Y Width Height')
Block \= namedtuple('Block', 'template start\_pos end\_pos name next')

# S形方块
S\_BLOCK = \[Block(\['.OO',
                  'OO.',
                  '...'\], Point(0, 0), Point(2, 1), 'S', 1),
           Block(\['O..',
                  'OO.',
                  '.O.'\], Point(0, 0), Point(1, 2), 'S', 0)\]
# Z形方块
Z\_BLOCK = \[Block(\['OO.',
                  '.OO',
                  '...'\], Point(0, 0), Point(2, 1), 'Z', 1),
           Block(\['.O.',
                  'OO.',
                  'O..'\], Point(0, 0), Point(1, 2), 'Z', 0)\]
# I型方块
I\_BLOCK = \[Block(\['.O..',
                  '.O..',
                  '.O..',
                  '.O..'\], Point(1, 0), Point(1, 3), 'I', 1),
           Block(\['....',
                  '....',
                  'OOOO',
                  '....'\], Point(0, 2), Point(3, 2), 'I', 0)\]
# O型方块
O\_BLOCK = \[Block(\['OO',
                  'OO'\], Point(0, 0), Point(1, 1), 'O', 0)\]
# J型方块
J\_BLOCK = \[Block(\['O..',
                  'OOO',
                  '...'\], Point(0, 0), Point(2, 1), 'J', 1),
           Block(\['.OO',
                  '.O.',
                  '.O.'\], Point(1, 0), Point(2, 2), 'J', 2),
           Block(\['...',
                  'OOO',
                  '..O'\], Point(0, 1), Point(2, 2), 'J', 3),
           Block(\['.O.',
                  '.O.',
                  'OO.'\], Point(0, 0), Point(1, 2), 'J', 0)\]
# L型方块
L\_BLOCK = \[Block(\['..O',
                  'OOO',
                  '...'\], Point(0, 0), Point(2, 1), 'L', 1),
           Block(\['.O.',
                  '.O.',
                  '.OO'\], Point(1, 0), Point(2, 2), 'L', 2),
           Block(\['...',
                  'OOO',
                  'O..'\], Point(0, 1), Point(2, 2), 'L', 3),
           Block(\['OO.',
                  '.O.',
                  '.O.'\], Point(0, 0), Point(1, 2), 'L', 0)\]
# T型方块
T\_BLOCK = \[Block(\['.O.',
                  'OOO',
                  '...'\], Point(0, 0), Point(2, 1), 'T', 1),
           Block(\['.O.',
                  '.OO',
                  '.O.'\], Point(1, 0), Point(2, 2), 'T', 2),
           Block(\['...',
                  'OOO',
                  '.O.'\], Point(0, 1), Point(2, 2), 'T', 3),
           Block(\['.O.',
                  'OO.',
                  '.O.'\], Point(0, 0), Point(1, 2), 'T', 0)\]

BLOCKS \= {'O': O\_BLOCK,
          'I': I\_BLOCK,
          'Z': Z\_BLOCK,
          'T': T\_BLOCK,
          'L': L\_BLOCK,
          'S': S\_BLOCK,
          'J': J\_BLOCK}

def get\_block():
    block\_name \= random.choice('OIZTLSJ')
    b \= BLOCKS\[block\_name\]
    idx \= random.randint(0, len(b) - 1)
    return b\[idx\]

def get\_next\_block(block):
    b \= BLOCKS\[block.name\]
    return b\[block.next\]
  • 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

游戏主代码

import sys
import time
import pygame
from pygame.locals import \*
import blocks

SIZE \= 30  # 每个小方格大小
BLOCK\_HEIGHT = 25  # 游戏区高度
BLOCK\_WIDTH = 10   # 游戏区宽度
BORDER\_WIDTH = 4   # 游戏区边框宽度
BORDER\_COLOR = (40, 40, 200)  # 游戏区边框颜色
SCREEN\_WIDTH = SIZE \* (BLOCK\_WIDTH + 5)  # 游戏屏幕的宽
SCREEN\_HEIGHT = SIZE \* BLOCK\_HEIGHT      # 游戏屏幕的高
BG\_COLOR = (40, 40, 60)  # 背景色
BLOCK\_COLOR = (20, 128, 200)  #
BLACK = (0, 0, 0)
RED \= (200, 30, 30)      # GAME OVER 的字体颜色

def print\_text(screen, font, x, y, text, fcolor=(255, 255, 255)):
    imgText \= font.render(text, True, fcolor)
    screen.blit(imgText, (x, y))

def main():
    pygame.init()
    screen \= pygame.display.set\_mode((SCREEN\_WIDTH, SCREEN\_HEIGHT))
    pygame.display.set\_caption('俄罗斯方块')

    font1 \= pygame.font.SysFont('SimHei', 24)  # 黑体24
    font2 = pygame.font.Font(None, 72)  # GAME OVER 的字体
    font\_pos\_x = BLOCK\_WIDTH \* SIZE + BORDER\_WIDTH + 10  # 右侧信息显示区域字体位置的X坐标
    gameover\_size = font2.size('GAME OVER')
    font1\_height \= int(font1.size('得分')\[1\])

    cur\_block \= None   # 当前下落方块
    next\_block = None  # 下一个方块
    cur\_pos\_x, cur\_pos\_y = 0, 0

    game\_area \= None    # 整个游戏区域
    game\_over = True
    start \= False       # 是否开始,当start = True,game\_over = True 时,才显示 GAME OVER
    score = 0           # 得分
    orispeed = 0.5      # 原始速度
    speed = orispeed    # 当前速度
    pause = False       # 暂停
    last\_drop\_time = None   # 上次下落时间
    last\_press\_time = None  # 上次按键时间

    def \_dock():
        nonlocal cur\_block, next\_block, game\_area, cur\_pos\_x, cur\_pos\_y, game\_over, score, speed
        for \_i in range(cur\_block.start\_pos.Y, cur\_block.end\_pos.Y + 1):
            for \_j in range(cur\_block.start\_pos.X, cur\_block.end\_pos.X + 1):
                if cur\_block.template\[\_i\]\[\_j\] != '.':
                    game\_area\[cur\_pos\_y \+ \_i\]\[cur\_pos\_x + \_j\] = '0'
        if cur\_pos\_y + cur\_block.start\_pos.Y <= 0:
            game\_over \= True
        else:
            # 计算消除
            remove\_idxs = \[\]
            for \_i in range(cur\_block.start\_pos.Y, cur\_block.end\_pos.Y + 1):
                if all(\_x == '0' for \_x in game\_area\[cur\_pos\_y + \_i\]):
                    remove\_idxs.append(cur\_pos\_y + \_i)
            if remove\_idxs:
                # 计算得分
                remove\_count = len(remove\_idxs)
                if remove\_count == 1:
                    score += 100
                elif remove\_count == 2:
                    score += 300
                elif remove\_count == 3:
                    score += 700
                elif remove\_count == 4:
                    score += 1500
                speed \= orispeed - 0.03 \* (score // 10000)
                # 消除
                \_i = \_j = remove\_idxs\[-1\]
                while \_i >= 0:
                    while \_j in remove\_idxs:
                        \_j \-= 1
                    if \_j < 0:
                        game\_area\[\_i\] \= \['.'\] \* BLOCK\_WIDTH
                    else:
                        game\_area\[\_i\] \= game\_area\[\_j\]
                    \_i \-= 1
                    \_j \-= 1
            cur\_block \= next\_block
            next\_block \= blocks.get\_block()
            cur\_pos\_x, cur\_pos\_y \= (BLOCK\_WIDTH - cur\_block.end\_pos.X - 1) // 2, -1 - cur\_block.end\_pos.Y

    def \_judge(pos\_x, pos\_y, block):
        nonlocal game\_area
        for \_i in range(block.start\_pos.Y, block.end\_pos.Y + 1):
            if pos\_y + block.end\_pos.Y >= BLOCK\_HEIGHT:
                return False
            for \_j in range(block.start\_pos.X, block.end\_pos.X + 1):
                if pos\_y + \_i >= 0 and block.template\[\_i\]\[\_j\] != '.' and game\_area\[pos\_y + \_i\]\[pos\_x + \_j\] != '.':
                    return False
        return True

    while True:
        for event in pygame.event.get():
            if event.type == QUIT:
                sys.exit()
            elif event.type == KEYDOWN:
                if event.key == K\_RETURN:
                    if game\_over:
                        start \= True
                        game\_over \= False
                        score \= 0
                        last\_drop\_time \= time.time()
                        last\_press\_time \= time.time()
                        game\_area \= \[\['.'\] \* BLOCK\_WIDTH for \_ in range(BLOCK\_HEIGHT)\]
                        cur\_block \= blocks.get\_block()
                        next\_block \= blocks.get\_block()
                        cur\_pos\_x, cur\_pos\_y \= (BLOCK\_WIDTH - cur\_block.end\_pos.X - 1) // 2, -1 - cur\_block.end\_pos.Y
                elif event.key == K\_SPACE:
                    if not game\_over:
                        pause \= not pause
                elif event.key in (K\_w, K\_UP):

                    if 0 <= cur\_pos\_x <= BLOCK\_WIDTH - len(cur\_block.template\[0\]):
                        \_next\_block \= blocks.get\_next\_block(cur\_block)
                        if \_judge(cur\_pos\_x, cur\_pos\_y, \_next\_block):
                            cur\_block \= \_next\_block

        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K\_LEFT:
                if not game\_over and not pause:
                    if time.time() - last\_press\_time > 0.1:
                        last\_press\_time \= time.time()
                        if cur\_pos\_x > - cur\_block.start\_pos.X:
                            if \_judge(cur\_pos\_x - 1, cur\_pos\_y, cur\_block):
                                cur\_pos\_x \-= 1
            if event.key == pygame.K\_RIGHT:
                if not game\_over and not pause:
                    if time.time() - last\_press\_time > 0.1:
                        last\_press\_time \= time.time()
                        # 不能移除右边框
                        if cur\_pos\_x + cur\_block.end\_pos.X + 1 < BLOCK\_WIDTH:
                            if \_judge(cur\_pos\_x + 1, cur\_pos\_y, cur\_block):
                                cur\_pos\_x += 1
            if event.key == pygame.K\_DOWN:
                if not game\_over and not pause:
                    if time.time() - last\_press\_time > 0.1:
                        last\_press\_time \= time.time()
                        if not \_judge(cur\_pos\_x, cur\_pos\_y + 1, cur\_block):
                            \_dock()
                        else:
                            last\_drop\_time \= time.time()
                            cur\_pos\_y += 1

        \_draw\_background(screen)

        \_draw\_game\_area(screen, game\_area)

        \_draw\_gridlines(screen)

        \_draw\_info(screen, font1, font\_pos\_x, font1\_height, score)
        # 画显示信息中的下一个方块
        \_draw\_block(screen, next\_block, font\_pos\_x, 30 + (font1\_height + 6) \* 5, 0, 0)

        if not game\_over:
            cur\_drop\_time \= time.time()
            if cur\_drop\_time - last\_drop\_time > speed:
                if not pause:

                    if not \_judge(cur\_pos\_x, cur\_pos\_y + 1, cur\_block):
                        \_dock()
                    else:
                        last\_drop\_time \= cur\_drop\_time
                        cur\_pos\_y += 1
        else:
            if start:
                print\_text(screen, font2,
                           (SCREEN\_WIDTH \- gameover\_size\[0\]) // 2, (SCREEN\_HEIGHT - gameover\_size\[1\]) // 2,
                           'GAME OVER', RED)

        # 画当前下落方块
        \_draw\_block(screen, cur\_block, 0, 0, cur\_pos\_x, cur\_pos\_y)

        pygame.display.flip()

# 画背景
def \_draw\_background(screen):
    # 填充背景色
    screen.fill(BG\_COLOR)
    # 画游戏区域分隔线
    pygame.draw.line(screen, BORDER\_COLOR,
                     (SIZE \* BLOCK\_WIDTH + BORDER\_WIDTH // 2, 0),
                     (SIZE \* BLOCK\_WIDTH + BORDER\_WIDTH // 2, SCREEN\_HEIGHT), BORDER\_WIDTH)

# 画网格线
def \_draw\_gridlines(screen):
    # 画网格线 竖线
    for x in range(BLOCK\_WIDTH):
        pygame.draw.line(screen, BLACK, (x \* SIZE, 0), (x \* SIZE, SCREEN\_HEIGHT), 1)
    # 画网格线 横线
    for y in range(BLOCK\_HEIGHT):
        pygame.draw.line(screen, BLACK, (0, y \* SIZE), (BLOCK\_WIDTH \* SIZE, y \* SIZE), 1)

# 画已经落下的方块
def \_draw\_game\_area(screen, game\_area):
    if game\_area:
        for i, row in enumerate(game\_area):
            for j, cell in enumerate(row):
                if cell != '.':
                    pygame.draw.rect(screen, BLOCK\_COLOR, (j \* SIZE, i \* SIZE, SIZE, SIZE), 0)

# 画单个方块
def \_draw\_block(screen, block, offset\_x, offset\_y, pos\_x, pos\_y):
    if block:
        for i in range(block.start\_pos.Y, block.end\_pos.Y + 1):
            for j in range(block.start\_pos.X, block.end\_pos.X + 1):
                if block.template\[i\]\[j\] != '.':
                    pygame.draw.rect(screen, BLOCK\_COLOR,
                                     (offset\_x \+ (pos\_x + j) \* SIZE, offset\_y + (pos\_y + i) \* SIZE, SIZE, SIZE), 0)

# 画得分等信息
def \_draw\_info(screen, font, pos\_x, font\_height, score):
    print\_text(screen, font, pos\_x, 10, f'得分: ')
    print\_text(screen, font, pos\_x, 10 + font\_height + 6, f'{score}')
    print\_text(screen, font, pos\_x, 20 + (font\_height + 6) \* 2, f'速度: ')
    print\_text(screen, font, pos\_x, 20 + (font\_height + 6) \* 3, f'{score // 10000}')
    print\_text(screen, font, pos\_x, 30 + (font\_height + 6) \* 4, f'下一个:')

if \_\_name\_\_ == '\_\_main\_\_':
    main()
  • 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
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183
  • 184
  • 185
  • 186
  • 187
  • 188
  • 189
  • 190
  • 191
  • 192
  • 193
  • 194
  • 195
  • 196
  • 197
  • 198
  • 199
  • 200
  • 201
  • 202
  • 203
  • 204
  • 205
  • 206
  • 207
  • 208
  • 209
  • 210
  • 211
  • 212
  • 213
  • 214
  • 215
  • 216
  • 217
  • 218
  • 219
  • 220
  • 221
  • 222
  • 223
  • 224
  • 225
  • 226
2、扫雷

地雷部分
一样的,单独保存py文件,mineblock.py

import random
from enum import Enum

BLOCK\_WIDTH \= 30
BLOCK\_HEIGHT \= 16
SIZE \= 20           # 块大小
MINE\_COUNT = 99     # 地雷数

class BlockStatus(Enum):
    normal \= 1  # 未点击
    opened = 2  # 已点击
    mine = 3    # 地雷
    flag = 4    # 标记为地雷
    ask = 5     # 标记为问号
    bomb = 6    # 踩中地雷
    hint = 7    # 被双击的周围
    double = 8  # 正被鼠标左右键双击

class Mine:
    def \_\_init\_\_(self, x, y, value=0):
        self.\_x \= x
        self.\_y \= y
        self.\_value \= 0
        self.\_around\_mine\_count \= -1
        self.\_status \= BlockStatus.normal
        self.set\_value(value)

    def \_\_repr\_\_(self):
        return str(self.\_value)
        # return f'({self.\_x},{self.\_y})={self.\_value}, status={self.status}'

    def get\_x(self):
        return self.\_x

    def set\_x(self, x):
        self.\_x \= x

    x \= property(fget=get\_x, fset=set\_x)

    def get\_y(self):
        return self.\_y

    def set\_y(self, y):
        self.\_y \= y

    y \= property(fget=get\_y, fset=set\_y)

    def get\_value(self):
        return self.\_value

    def set\_value(self, value):
        if value:
            self.\_value \= 1
        else:
            self.\_value \= 0

    value \= property(fget=get\_value, fset=set\_value, doc='0:非地雷 1:雷')

    def get\_around\_mine\_count(self):
        return self.\_around\_mine\_count

    def set\_around\_mine\_count(self, around\_mine\_count):
        self.\_around\_mine\_count \= around\_mine\_count

    around\_mine\_count \= property(fget=get\_around\_mine\_count, fset=set\_around\_mine\_count, doc='四周地雷数量')

    def get\_status(self):
        return self.\_status

    def set\_status(self, value):
        self.\_status \= value

    status \= property(fget=get\_status, fset=set\_status, doc='BlockStatus')

class MineBlock:
    def \_\_init\_\_(self):
        self.\_block \= \[\[Mine(i, j) for i in range(BLOCK\_WIDTH)\] for j in range(BLOCK\_HEIGHT)\]

        # 埋雷
        for i in random.sample(range(BLOCK\_WIDTH \* BLOCK\_HEIGHT), MINE\_COUNT):
            self.\_block\[i // BLOCK\_WIDTH\]\[i % BLOCK\_WIDTH\].value = 1

    def get\_block(self):
        return self.\_block

    block \= property(fget=get\_block)

    def getmine(self, x, y):
        return self.\_block\[y\]\[x\]

    def open\_mine(self, x, y):
        # 踩到雷了
        if self.\_block\[y\]\[x\].value:
            self.\_block\[y\]\[x\].status \= BlockStatus.bomb
            return False

        # 先把状态改为 opened
        self.\_block\[y\]\[x\].status = BlockStatus.opened

        around \= \_get\_around(x, y)

        \_sum \= 0
        for i, j in around:
            if self.\_block\[j\]\[i\].value:
                \_sum += 1
        self.\_block\[y\]\[x\].around\_mine\_count \= \_sum

        # 如果周围没有雷,那么将周围8个未中未点开的递归算一遍
        # 这就能实现一点出现一大片打开的效果了
        if \_sum == 0:
            for i, j in around:
                if self.\_block\[j\]\[i\].around\_mine\_count == -1:
                    self.open\_mine(i, j)

        return True

    def double\_mouse\_button\_down(self, x, y):
        if self.\_block\[y\]\[x\].around\_mine\_count == 0:
            return True

        self.\_block\[y\]\[x\].status \= BlockStatus.double

        around \= \_get\_around(x, y)

        sumflag \= 0     # 周围被标记的雷数量
        for i, j in \_get\_around(x, y):
            if self.\_block\[j\]\[i\].status == BlockStatus.flag:
                sumflag += 1
        # 周边的雷已经全部被标记
        result = True
        if sumflag == self.\_block\[y\]\[x\].around\_mine\_count:
            for i, j in around:
                if self.\_block\[j\]\[i\].status == BlockStatus.normal:
                    if not self.open\_mine(i, j):
                        result \= False
        else:
            for i, j in around:
                if self.\_block\[j\]\[i\].status == BlockStatus.normal:
                    self.\_block\[j\]\[i\].status \= BlockStatus.hint
        return result

    def double\_mouse\_button\_up(self, x, y):
        self.\_block\[y\]\[x\].status \= BlockStatus.opened
        for i, j in \_get\_around(x, y):
            if self.\_block\[j\]\[i\].status == BlockStatus.hint:
                self.\_block\[j\]\[i\].status \= BlockStatus.normal

def \_get\_around(x, y):
    """返回(x, y)周围的点的坐标"""
    # 这里注意,range 末尾是开区间,所以要加 1
    return \[(i, j) for i in range(max(0, x - 1), min(BLOCK\_WIDTH - 1, x + 1) + 1)
            for j in range(max(0, y - 1), min(BLOCK\_HEIGHT - 1, y + 1) + 1) if i != x or j != y\]
  • 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
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152

素材

素材我都放在群里了,我还给大家准备了这些资料

# 一群:872937351 (群满了的话加二群)
# 二群:924040232
# python学习路线汇总
# 精品Python学习书籍100本
# Python入门视频合集
# Python实战案例
# Python面试题
# Python相关软件工具/pycharm永久激活
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

在这里插入图片描述

主代码

import sys
import time
from enum import Enum
import pygame
from pygame.locals import \*
from mineblock import \*

# 游戏屏幕的宽
SCREEN\_WIDTH = BLOCK\_WIDTH \* SIZE
# 游戏屏幕的高
SCREEN\_HEIGHT = (BLOCK\_HEIGHT + 2) \* SIZE

class GameStatus(Enum):
    readied \= 1,
    started \= 2,
    over \= 3,
    win \= 4

def print\_text(screen, font, x, y, text, fcolor=(255, 255, 255)):
    imgText \= font.render(text, True, fcolor)
    screen.blit(imgText, (x, y))

def main():
    pygame.init()
    screen \= pygame.display.set\_mode((SCREEN\_WIDTH, SCREEN\_HEIGHT))
    pygame.display.set\_caption('扫雷')

    font1 \= pygame.font.Font('resources/a.TTF', SIZE \* 2)  # 得分的字体
    fwidth, fheight = font1.size('999')
    red \= (200, 40, 40)

    # 加载资源图片,因为资源文件大小不一,所以做了统一的缩放处理
    img0 = pygame.image.load('resources/0.bmp').convert()
    img0 \= pygame.transform.smoothscale(img0, (SIZE, SIZE))
    img1 \= pygame.image.load('resources/1.bmp').convert()
    img1 \= pygame.transform.smoothscale(img1, (SIZE, SIZE))
    img2 \= pygame.image.load('resources/2.bmp').convert()
    img2 \= pygame.transform.smoothscale(img2, (SIZE, SIZE))
    img3 \= pygame.image.load('resources/3.bmp').convert()
    img3 \= pygame.transform.smoothscale(img3, (SIZE, SIZE))
    img4 \= pygame.image.load('resources/4.bmp').convert()
    img4 \= pygame.transform.smoothscale(img4, (SIZE, SIZE))
    img5 \= pygame.image.load('resources/5.bmp').convert()
    img5 \= pygame.transform.smoothscale(img5, (SIZE, SIZE))
    img6 \= pygame.image.load('resources/6.bmp').convert()
    img6 \= pygame.transform.smoothscale(img6, (SIZE, SIZE))
    img7 \= pygame.image.load('resources/7.bmp').convert()
    img7 \= pygame.transform.smoothscale(img7, (SIZE, SIZE))
    img8 \= pygame.image.load('resources/8.bmp').convert()
    img8 \= pygame.transform.smoothscale(img8, (SIZE, SIZE))
    img\_blank \= pygame.image.load('resources/blank.bmp').convert()
    img\_blank \= pygame.transform.smoothscale(img\_blank, (SIZE, SIZE))
    img\_flag \= pygame.image.load('resources/flag.bmp').convert()
    img\_flag \= pygame.transform.smoothscale(img\_flag, (SIZE, SIZE))
    img\_ask \= pygame.image.load('resources/ask.bmp').convert()
    img\_ask \= pygame.transform.smoothscale(img\_ask, (SIZE, SIZE))
    img\_mine \= pygame.image.load('resources/mine.bmp').convert()
    img\_mine \= pygame.transform.smoothscale(img\_mine, (SIZE, SIZE))
    img\_blood \= pygame.image.load('resources/blood.bmp').convert()
    img\_blood \= pygame.transform.smoothscale(img\_blood, (SIZE, SIZE))
    img\_error \= pygame.image.load('resources/error.bmp').convert()
    img\_error \= pygame.transform.smoothscale(img\_error, (SIZE, SIZE))
    face\_size \= int(SIZE \* 1.25)
    img\_face\_fail \= pygame.image.load('resources/face\_fail.bmp').convert()
    img\_face\_fail \= pygame.transform.smoothscale(img\_face\_fail, (face\_size, face\_size))
    img\_face\_normal \= pygame.image.load('resources/face\_normal.bmp').convert()
    img\_face\_normal \= pygame.transform.smoothscale(img\_face\_normal, (face\_size, face\_size))
    img\_face\_success \= pygame.image.load('resources/face\_success.bmp').convert()
    img\_face\_success \= pygame.transform.smoothscale(img\_face\_success, (face\_size, face\_size))
    face\_pos\_x \= (SCREEN\_WIDTH - face\_size) // 2
    face\_pos\_y \= (SIZE \* 2 - face\_size) // 2

    img\_dict \= {
        0: img0,
        1: img1,
        2: img2,
        3: img3,
        4: img4,
        5: img5,
        6: img6,
        7: img7,
        8: img8
    }

    bgcolor \= (225, 225, 225)   # 背景色
    block \= MineBlock()
    game\_status \= GameStatus.readied
    start\_time \= None   # 开始时间
    elapsed\_time = 0    # 耗时

    while True:
        # 填充背景色
        screen.fill(bgcolor)

        for event in pygame.event.get():
            if event.type == QUIT:
                sys.exit()
            elif event.type == MOUSEBUTTONDOWN:
                mouse\_x, mouse\_y \= event.pos
                x \= mouse\_x // SIZE
                y \= mouse\_y // SIZE - 2
                b1, b2, b3 \= pygame.mouse.get\_pressed()
                if game\_status == GameStatus.started:
                    # 鼠标左右键同时按下,如果已经标记了所有雷,则打开周围一圈
                    # 如果还未标记完所有雷,则有一个周围一圈被同时按下的效果
                    if b1 and b3:
                        mine \= block.getmine(x, y)
                        if mine.status == BlockStatus.opened:
                            if not block.double\_mouse\_button\_down(x, y):
                                game\_status \= GameStatus.over
            elif event.type == MOUSEBUTTONUP:
                if y < 0:
                    if face\_pos\_x <= mouse\_x <= face\_pos\_x + face\_size \\
                            and face\_pos\_y <= mouse\_y <= face\_pos\_y + face\_size:
                        game\_status \= GameStatus.readied
                        block \= MineBlock()
                        start\_time \= time.time()
                        elapsed\_time \= 0
                        continue

                if game\_status == GameStatus.readied:
                    game\_status \= GameStatus.started
                    start\_time \= time.time()
                    elapsed\_time \= 0

                if game\_status == GameStatus.started:
                    mine \= block.getmine(x, y)
                    if b1 and not b3:       # 按鼠标左键
                        if mine.status == BlockStatus.normal:
                            if not block.open\_mine(x, y):
                                game\_status \= GameStatus.over
                    elif not b1 and b3:     # 按鼠标右键
                        if mine.status == BlockStatus.normal:
                            mine.status \= BlockStatus.flag
                        elif mine.status == BlockStatus.flag:
                            mine.status \= BlockStatus.ask
                        elif mine.status == BlockStatus.ask:
                            mine.status \= BlockStatus.normal
                    elif b1 and b3:
                        if mine.status == BlockStatus.double:
                            block.double\_mouse\_button\_up(x, y)

        flag\_count \= 0
        opened\_count \= 0

        for row in block.block:
            for mine in row:
                pos \= (mine.x \* SIZE, (mine.y + 2) \* SIZE)
                if mine.status == BlockStatus.opened:
                    screen.blit(img\_dict\[mine.around\_mine\_count\], pos)
                    opened\_count += 1
                elif mine.status == BlockStatus.double:
                    screen.blit(img\_dict\[mine.around\_mine\_count\], pos)
                elif mine.status == BlockStatus.bomb:
                    screen.blit(img\_blood, pos)
                elif mine.status == BlockStatus.flag:
                    screen.blit(img\_flag, pos)
                    flag\_count += 1
                elif mine.status == BlockStatus.ask:
                    screen.blit(img\_ask, pos)
                elif mine.status == BlockStatus.hint:
                    screen.blit(img0, pos)
                elif game\_status == GameStatus.over and mine.value:
                    screen.blit(img\_mine, pos)
                elif mine.value == 0 and mine.status == BlockStatus.flag:
                    screen.blit(img\_error, pos)
                elif mine.status == BlockStatus.normal:
                    screen.blit(img\_blank, pos)

        print\_text(screen, font1, 30, (SIZE \* 2 - fheight) // 2 - 2, '%02d' % (MINE\_COUNT - flag\_count), red)
        if game\_status == GameStatus.started:
            elapsed\_time \= int(time.time() - start\_time)
        print\_text(screen, font1, SCREEN\_WIDTH \- fwidth - 30, (SIZE \* 2 - fheight) // 2 - 2, '%03d' % elapsed\_time, red)

        if flag\_count + opened\_count == BLOCK\_WIDTH \* BLOCK\_HEIGHT:
            game\_status \= GameStatus.win

        if game\_status == GameStatus.over:
            screen.blit(img\_face\_fail, (face\_pos\_x, face\_pos\_y))
        elif game\_status == GameStatus.win:
            screen.blit(img\_face\_success, (face\_pos\_x, face\_pos\_y))
        else:
            screen.blit(img\_face\_normal, (face\_pos\_x, face\_pos\_y))

        pygame.display.update()

if \_\_name\_\_ == '\_\_main\_\_':
    main()
  • 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
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183
  • 184
  • 185
  • 186
  • 187
  • 188
3、五子棋

五子棋就没那么多七七八八的素材和其它代码了

import sys
import random
import pygame
from pygame.locals import \*
import pygame.gfxdraw
from collections import namedtuple

Chessman \= namedtuple('Chessman', 'Name Value Color')
Point \= namedtuple('Point', 'X Y')

BLACK\_CHESSMAN \= Chessman('黑子', 1, (45, 45, 45))
WHITE\_CHESSMAN \= Chessman('白子', 2, (219, 219, 219))

offset \= \[(1, 0), (0, 1), (1, 1), (1, -1)\]

class Checkerboard:
    def \_\_init\_\_(self, line\_points):
        self.\_line\_points \= line\_points
        self.\_checkerboard \= \[\[0\] \* line\_points for \_ in range(line\_points)\]

    def \_get\_checkerboard(self):
        return self.\_checkerboard

    checkerboard \= property(\_get\_checkerboard)

    # 判断是否可落子
    def can\_drop(self, point):
        return self.\_checkerboard\[point.Y\]\[point.X\] == 0

    def drop(self, chessman, point):
        """
        落子
        :param chessman:
        :param point:落子位置
        :return:若该子落下之后即可获胜,则返回获胜方,否则返回 None
        """
        print(f'{chessman.Name} ({point.X}, {point.Y})')
        self.\_checkerboard\[point.Y\]\[point.X\] \= chessman.Value

        if self.\_win(point):
            print(f'{chessman.Name}获胜')
            return chessman

    # 判断是否赢了
    def \_win(self, point):
        cur\_value \= self.\_checkerboard\[point.Y\]\[point.X\]
        for os in offset:
            if self.\_get\_count\_on\_direction(point, cur\_value, os\[0\], os\[1\]):
                return True

    def \_get\_count\_on\_direction(self, point, value, x\_offset, y\_offset):
        count \= 1
        for step in range(1, 5):
            x \= point.X + step \* x\_offset
            y \= point.Y + step \* y\_offset
            if 0 <= x < self.\_line\_points and 0 <= y < self.\_line\_points and self.\_checkerboard\[y\]\[x\] == value:
                count += 1
            else:
                break
        for step in range(1, 5):
            x \= point.X - step \* x\_offset
            y \= point.Y - step \* y\_offset
            if 0 <= x < self.\_line\_points and 0 <= y < self.\_line\_points and self.\_checkerboard\[y\]\[x\] == value:
                count += 1
            else:
                break

        return count >= 5

SIZE \= 30  # 棋盘每个点时间的间隔
Line\_Points = 19  # 棋盘每行/每列点数
Outer\_Width = 20  # 棋盘外宽度
Border\_Width = 4  # 边框宽度
Inside\_Width = 4  # 边框跟实际的棋盘之间的间隔
Border\_Length = SIZE \* (Line\_Points - 1) + Inside\_Width \* 2 + Border\_Width  # 边框线的长度
Start\_X = Start\_Y = Outer\_Width + int(Border\_Width / 2) + Inside\_Width  # 网格线起点(左上角)坐标
SCREEN\_HEIGHT = SIZE \* (Line\_Points - 1) + Outer\_Width \* 2 + Border\_Width + Inside\_Width \* 2  # 游戏屏幕的高
SCREEN\_WIDTH = SCREEN\_HEIGHT + 200  # 游戏屏幕的宽
Stone\_Radius \= SIZE // 2 - 3  # 棋子半径
Stone\_Radius2 = SIZE // 2 + 3
Checkerboard\_Color \= (0xE3, 0x92, 0x65)  # 棋盘颜色
BLACK\_COLOR = (0, 0, 0)
WHITE\_COLOR \= (255, 255, 255)
RED\_COLOR \= (200, 30, 30)
BLUE\_COLOR \= (30, 30, 200)

RIGHT\_INFO\_POS\_X \= SCREEN\_HEIGHT + Stone\_Radius2 \* 2 + 10

def print\_text(screen, font, x, y, text, fcolor=(255, 255, 255)):
    imgText \= font.render(text, True, fcolor)
    screen.blit(imgText, (x, y))

def main():
    pygame.init()
    screen \= pygame.display.set\_mode((SCREEN\_WIDTH, SCREEN\_HEIGHT))
    pygame.display.set\_caption('五子棋')

    font1 \= pygame.font.SysFont('SimHei', 32)
    font2 \= pygame.font.SysFont('SimHei', 72)
    fwidth, fheight \= font2.size('黑方获胜')

    checkerboard \= Checkerboard(Line\_Points)
    cur\_runner \= BLACK\_CHESSMAN
    winner \= None
    computer \= AI(Line\_Points, WHITE\_CHESSMAN)

    black\_win\_count \= 0
    white\_win\_count \= 0

    while True:
        for event in pygame.event.get():
            if event.type == QUIT:
                sys.exit()
            elif event.type == KEYDOWN:
                if event.key == K\_RETURN:
                    if winner is not None:
                        winner \= None
                        cur\_runner \= BLACK\_CHESSMAN
                        checkerboard \= Checkerboard(Line\_Points)
                        computer \= AI(Line\_Points, WHITE\_CHESSMAN)
            elif event.type == MOUSEBUTTONDOWN:
                if winner is None:
                    pressed\_array \= pygame.mouse.get\_pressed()
                    if pressed\_array\[0\]:
                        mouse\_pos \= pygame.mouse.get\_pos()
                        click\_point \= \_get\_clickpoint(mouse\_pos)
                        if click\_point is not None:
                            if checkerboard.can\_drop(click\_point):
                                winner \= checkerboard.drop(cur\_runner, click\_point)
                                if winner is None:
                                    cur\_runner \= \_get\_next(cur\_runner)
                                    computer.get\_opponent\_drop(click\_point)
                                    AI\_point \= computer.AI\_drop()
                                    winner \= checkerboard.drop(cur\_runner, AI\_point)
                                    if winner is not None:
                                        white\_win\_count += 1
                                    cur\_runner \= \_get\_next(cur\_runner)
                                else:
                                    black\_win\_count += 1
                        else:
                            print('超出棋盘区域')

        # 画棋盘
        \_draw\_checkerboard(screen)

        # 画棋盘上已有的棋子
        for i, row in enumerate(checkerboard.checkerboard):
            for j, cell in enumerate(row):
                if cell == BLACK\_CHESSMAN.Value:
                    \_draw\_chessman(screen, Point(j, i), BLACK\_CHESSMAN.Color)
                elif cell == WHITE\_CHESSMAN.Value:
                    \_draw\_chessman(screen, Point(j, i), WHITE\_CHESSMAN.Color)

        \_draw\_left\_info(screen, font1, cur\_runner, black\_win\_count, white\_win\_count)

        if winner:
            print\_text(screen, font2, (SCREEN\_WIDTH \- fwidth)//2, (SCREEN\_HEIGHT - fheight)//2, winner.Name + '获胜', RED\_COLOR)

        pygame.display.flip()

def \_get\_next(cur\_runner):
    if cur\_runner == BLACK\_CHESSMAN:
        return WHITE\_CHESSMAN
    else:
        return BLACK\_CHESSMAN

# 画棋盘
def \_draw\_checkerboard(screen):
    # 填充棋盘背景色
    screen.fill(Checkerboard\_Color)
    # 画棋盘网格线外的边框
    pygame.draw.rect(screen, BLACK\_COLOR, (Outer\_Width, Outer\_Width, Border\_Length, Border\_Length), Border\_Width)
    # 画网格线
    for i in range(Line\_Points):
        pygame.draw.line(screen, BLACK\_COLOR,
                         (Start\_Y, Start\_Y \+ SIZE \* i),
                         (Start\_Y \+ SIZE \* (Line\_Points - 1), Start\_Y + SIZE \* i),
                         1)
    for j in range(Line\_Points):
        pygame.draw.line(screen, BLACK\_COLOR,
                         (Start\_X \+ SIZE \* j, Start\_X),
                         (Start\_X \+ SIZE \* j, Start\_X + SIZE \* (Line\_Points - 1)),
                         1)
    # 画星位和天元
    for i in (3, 9, 15):
        for j in (3, 9, 15):
            if i == j == 9:
                radius \= 5
            else:
                radius \= 3
            # pygame.draw.circle(screen, BLACK, (Start\_X + SIZE \* i, Start\_Y + SIZE \* j), radius)
            pygame.gfxdraw.aacircle(screen, Start\_X + SIZE \* i, Start\_Y + SIZE \* j, radius, BLACK\_COLOR)
            pygame.gfxdraw.filled\_circle(screen, Start\_X \+ SIZE \* i, Start\_Y + SIZE \* j, radius, BLACK\_COLOR)

# 画棋子
def \_draw\_chessman(screen, point, stone\_color):
    # pygame.draw.circle(screen, stone\_color, (Start\_X + SIZE \* point.X, Start\_Y + SIZE \* point.Y), Stone\_Radius)
    pygame.gfxdraw.aacircle(screen, Start\_X + SIZE \* point.X, Start\_Y + SIZE \* point.Y, Stone\_Radius, stone\_color)
    pygame.gfxdraw.filled\_circle(screen, Start\_X \+ SIZE \* point.X, Start\_Y + SIZE \* point.Y, Stone\_Radius, stone\_color)

# 画左侧信息显示
def \_draw\_left\_info(screen, font, cur\_runner, black\_win\_count, white\_win\_count):
    \_draw\_chessman\_pos(screen, (SCREEN\_HEIGHT \+ Stone\_Radius2, Start\_X + Stone\_Radius2), BLACK\_CHESSMAN.Color)
    \_draw\_chessman\_pos(screen, (SCREEN\_HEIGHT \+ Stone\_Radius2, Start\_X + Stone\_Radius2 \* 4), WHITE\_CHESSMAN.Color)

    print\_text(screen, font, RIGHT\_INFO\_POS\_X, Start\_X \+ 3, '玩家', BLUE\_COLOR)
    print\_text(screen, font, RIGHT\_INFO\_POS\_X, Start\_X \+ Stone\_Radius2 \* 3 + 3, '电脑', BLUE\_COLOR)

    print\_text(screen, font, SCREEN\_HEIGHT, SCREEN\_HEIGHT \- Stone\_Radius2 \* 8, '战况:', BLUE\_COLOR)
    \_draw\_chessman\_pos(screen, (SCREEN\_HEIGHT \+ Stone\_Radius2, SCREEN\_HEIGHT - int(Stone\_Radius2 \* 4.5)), BLACK\_CHESSMAN.Color)
    \_draw\_chessman\_pos(screen, (SCREEN\_HEIGHT \+ Stone\_Radius2, SCREEN\_HEIGHT - Stone\_Radius2 \* 2), WHITE\_CHESSMAN.Color)
    print\_text(screen, font, RIGHT\_INFO\_POS\_X, SCREEN\_HEIGHT \- int(Stone\_Radius2 \* 5.5) + 3, f'{black\_win\_count} 胜', BLUE\_COLOR)
    print\_text(screen, font, RIGHT\_INFO\_POS\_X, SCREEN\_HEIGHT \- Stone\_Radius2 \* 3 + 3, f'{white\_win\_count} 胜', BLUE\_COLOR)

def \_draw\_chessman\_pos(screen, pos, stone\_color):
    pygame.gfxdraw.aacircle(screen, pos\[0\], pos\[1\], Stone\_Radius2, stone\_color)
    pygame.gfxdraw.filled\_circle(screen, pos\[0\], pos\[1\], Stone\_Radius2, stone\_color)

# 根据鼠标点击位置,返回游戏区坐标
def \_get\_clickpoint(click\_pos):
    pos\_x \= click\_pos\[0\] - Start\_X
    pos\_y \= click\_pos\[1\] - Start\_Y
    if pos\_x < -Inside\_Width or pos\_y < -Inside\_Width:
        return None
    x \= pos\_x // SIZE
    y \= pos\_y // SIZE
    if pos\_x % SIZE > Stone\_Radius:
        x += 1
    if pos\_y % SIZE > Stone\_Radius:
        y += 1
    if x >= Line\_Points or y >= Line\_Points:
        return None

    return Point(x, y)

class AI:
    def \_\_init\_\_(self, line\_points, chessman):
        self.\_line\_points \= line\_points
        self.\_my \= chessman
        self.\_opponent \= BLACK\_CHESSMAN if chessman == WHITE\_CHESSMAN else WHITE\_CHESSMAN
        self.\_checkerboard \= \[\[0\] \* line\_points for \_ in range(line\_points)\]

    def get\_opponent\_drop(self, point):
        self.\_checkerboard\[point.Y\]\[point.X\] \= self.\_opponent.Value

    def AI\_drop(self):
        point \= None
        score \= 0
        for i in range(self.\_line\_points):
            for j in range(self.\_line\_points):
                if self.\_checkerboard\[j\]\[i\] == 0:
                    \_score \= self.\_get\_point\_score(Point(i, j))
                    if \_score > score:
                        score \= \_score
                        point \= Point(i, j)
                    elif \_score == score and \_score > 0:
                        r \= random.randint(0, 100)
                        if r % 2 == 0:
                            point \= Point(i, j)
        self.\_checkerboard\[point.Y\]\[point.X\] \= self.\_my.Value
        return point

    def \_get\_point\_score(self, point):
        score \= 0
        for os in offset:
            score += self.\_get\_direction\_score(point, os\[0\], os\[1\])
        return score

    def \_get\_direction\_score(self, point, x\_offset, y\_offset):
        count \= 0   # 落子处我方连续子数
        \_count = 0  # 落子处对方连续子数
        space = None   # 我方连续子中有无空格
        \_space = None  # 对方连续子中有无空格
        both = 0    # 我方连续子两端有无阻挡
        \_both = 0   # 对方连续子两端有无阻挡

        # 如果是 1 表示是边上是我方子,2 表示敌方子
        flag = self.\_get\_stone\_color(point, x\_offset, y\_offset, True)
        if flag != 0:
            for step in range(1, 6):
                x \= point.X + step \* x\_offset
                y \= point.Y + step \* y\_offset
                if 0 <= x < self.\_line\_points and 0 <= y < self.\_line\_points:
                    if flag == 1:
                        if self.\_checkerboard\[y\]\[x\] == self.\_my.Value:
                            count += 1
                            if space is False:
                                space \= True
                        elif self.\_checkerboard\[y\]\[x\] == self.\_opponent.Value:
                            \_both += 1
                            break
                        else:
                            if space is None:
                                space \= False
                            else:
                                break   # 遇到第二个空格退出
                    elif flag == 2:
                        if self.\_checkerboard\[y\]\[x\] == self.\_my.Value:
                            \_both += 1
                            break
                        elif self.\_checkerboard\[y\]\[x\] == self.\_opponent.Value:
                            \_count += 1
                            if \_space is False:
                                \_space \= True
                        else:
                            if \_space is None:
                                \_space \= False
                            else:
                                break
                else:
                    # 遇到边也就是阻挡
                    if flag == 1:
                        both += 1
                    elif flag == 2:
                        \_both += 1

        if space is False:
            space \= None
        if \_space is False:
            \_space \= None

        \_flag \= self.\_get\_stone\_color(point, -x\_offset, -y\_offset, True)
        if \_flag != 0:
            for step in range(1, 6):
                x \= point.X - step \* x\_offset
                y \= point.Y - step \* y\_offset
                if 0 <= x < self.\_line\_points and 0 <= y < self.\_line\_points:
                    if \_flag == 1:
                        if self.\_checkerboard\[y\]\[x\] == self.\_my.Value:
                            count += 1
                            if space is False:
                                space \= True
                        elif self.\_checkerboard\[y\]\[x\] == self.\_opponent.Value:
                            \_both += 1
                            break
                        else:
                            if space is None:
                                space \= False
                            else:
                                break   # 遇到第二个空格退出
                    elif \_flag == 2:
                        if self.\_checkerboard\[y\]\[x\] == self.\_my.Value:
                            \_both += 1
                            break
                        elif self.\_checkerboard\[y\]\[x\] == self.\_opponent.Value:
                            \_count += 1
                            if \_space is False:
                                \_space \= True
                        else:
                            if \_space is None:
                                \_space \= False
                            else:
                                break
                else:
                    # 遇到边也就是阻挡
                    if \_flag == 1:
                        both += 1
                    elif \_flag == 2:
                        \_both += 1

        score \= 0
        if count == 4:
            score \= 10000
        elif \_count == 4:
            score \= 9000
        elif count == 3:
            if both == 0:
                score \= 1000
            elif both == 1:
                score \= 100
            else:
                score \= 0
        elif \_count == 3:
            if \_both == 0:
                score \= 900
            elif \_both == 1:
                score \= 90
            else:
                score \= 0
        elif count == 2:
            if both == 0:
                score \= 100
            elif both == 1:
                score \= 10
            else:
                score \= 0
        elif \_count == 2:
            if \_both == 0:
                score \= 90
            elif \_both == 1:
                score \= 9
            else:
                score \= 0
        elif count == 1:
            score \= 10
        elif \_count == 1:
            score \= 9
        else:
            score \= 0

        if space or \_space:
            score /= 2

        return score

    # 判断指定位置处在指定方向上是我方子、对方子、空
    def \_get\_stone\_color(self, point, x\_offset, y\_offset, next):
        x \= point.X + x\_offset
        y \= point.Y + y\_offset
        if 0 <= x < self.\_line\_points and 0 <= y < self.\_line\_points:
            if self.\_checkerboard\[y\]\[x\] == self.\_my.Value:
                return 1
            elif self.\_checkerboard\[y\]\[x\] == self.\_opponent.Value:
                return 2
            else:
                if next:
                    return self.\_get\_stone\_color(Point(x, y), x\_offset, y\_offset, False)
                else:
                    return 0
        else:
            return 0

if \_\_name\_\_ == '\_\_main\_\_':
    main()
  • 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
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183
  • 184
  • 185
  • 186
  • 187
  • 188
  • 189
  • 190
  • 191
  • 192
  • 193
  • 194
  • 195
  • 196
  • 197
  • 198
  • 199
  • 200
  • 201
  • 202
  • 203
  • 204
  • 205
  • 206
  • 207
  • 208
  • 209
  • 210
  • 211
  • 212
  • 213
  • 214
  • 215
  • 216
  • 217
  • 218
  • 219
  • 220
  • 221
  • 222
  • 223
  • 224
  • 225
  • 226
  • 227
  • 228
  • 229
  • 230
  • 231
  • 232
  • 233
  • 234
  • 235
  • 236
  • 237
  • 238
  • 239
  • 240
  • 241
  • 242
  • 243
  • 244
  • 245
  • 246
  • 247
  • 248
  • 249
  • 250
  • 251
  • 252
  • 253
  • 254
  • 255
  • 256
  • 257
  • 258
  • 259
  • 260
  • 261
  • 262
  • 263
  • 264
  • 265
  • 266
  • 267
  • 268
  • 269
  • 270
  • 271
  • 272
  • 273
  • 274
  • 275
  • 276
  • 277
  • 278
  • 279
  • 280
  • 281
  • 282
  • 283
  • 284
  • 285
  • 286
  • 287
  • 288
  • 289
  • 290
  • 291
  • 292
  • 293
  • 294
  • 295
  • 296
  • 297
  • 298
  • 299
  • 300
  • 301
  • 302
  • 303
  • 304
  • 305
  • 306
  • 307
  • 308
  • 309
  • 310
  • 311
  • 312
  • 313
  • 314
  • 315
  • 316
  • 317
  • 318
  • 319
  • 320
  • 321
  • 322
  • 323
  • 324
  • 325
  • 326
  • 327
  • 328
  • 329
  • 330
  • 331
  • 332
  • 333
  • 334
  • 335
  • 336
  • 337
  • 338
  • 339
  • 340
  • 341
  • 342
  • 343
  • 344
  • 345
  • 346
  • 347
  • 348
  • 349
  • 350
  • 351
  • 352
  • 353
  • 354
  • 355
  • 356
  • 357
  • 358
  • 359
  • 360
  • 361
  • 362
  • 363
  • 364
  • 365
  • 366
  • 367
  • 368
  • 369
  • 370
  • 371
  • 372
  • 373
  • 374
  • 375
  • 376
  • 377
  • 378
  • 379
  • 380
  • 381
  • 382
  • 383
  • 384
  • 385
  • 386
  • 387
  • 388
  • 389
  • 390
  • 391
  • 392
  • 393
  • 394
  • 395
  • 396
  • 397
  • 398
  • 399
  • 400
  • 401
  • 402
  • 403
  • 404
  • 405
  • 406
  • 407
  • 408
  • 409
  • 410
  • 411
  • 412
  • 413
  • 414
  • 415
  • 416
  • 417
  • 418
  • 419
  • 420
  • 421
  • 422
  • 423
  • 424
4、贪吃蛇
import random
import sys
import time
import pygame
from pygame.locals import \*
from collections import deque

SCREEN\_WIDTH \= 600      # 屏幕宽度
SCREEN\_HEIGHT = 480     # 屏幕高度
SIZE = 20               # 小方格大小
LINE\_WIDTH = 1          # 网格线宽度

# 游戏区域的坐标范围
SCOPE\_X = (0, SCREEN\_WIDTH // SIZE - 1)
SCOPE\_Y \= (2, SCREEN\_HEIGHT // SIZE - 1)

# 食物的分值及颜色
FOOD\_STYLE\_LIST = \[(10, (255, 100, 100)), (20, (100, 255, 100)), (30, (100, 100, 255))\]

LIGHT \= (100, 100, 100)
DARK \= (200, 200, 200)      # 蛇的颜色
BLACK = (0, 0, 0)           # 网格线颜色
RED = (200, 30, 30)         # 红色,GAME OVER 的字体颜色
BGCOLOR = (40, 40, 60)      # 背景色

def print\_text(screen, font, x, y, text, fcolor=(255, 255, 255)):
    imgText \= font.render(text, True, fcolor)
    screen.blit(imgText, (x, y))

# 初始化蛇
def init\_snake():
    snake \= deque()
    snake.append((2, SCOPE\_Y\[0\]))
    snake.append((1, SCOPE\_Y\[0\]))
    snake.append((0, SCOPE\_Y\[0\]))
    return snake

def create\_food(snake):
    food\_x \= random.randint(SCOPE\_X\[0\], SCOPE\_X\[1\])
    food\_y \= random.randint(SCOPE\_Y\[0\], SCOPE\_Y\[1\])
    while (food\_x, food\_y) in snake:
        # 如果食物出现在蛇身上,则重来
        food\_x = random.randint(SCOPE\_X\[0\], SCOPE\_X\[1\])
        food\_y \= random.randint(SCOPE\_Y\[0\], SCOPE\_Y\[1\])
    return food\_x, food\_y

def get\_food\_style():
    return FOOD\_STYLE\_LIST\[random.randint(0, 2)\]

def main():
    pygame.init()
    screen \= pygame.display.set\_mode((SCREEN\_WIDTH, SCREEN\_HEIGHT))
    pygame.display.set\_caption('贪吃蛇')

    font1 \= pygame.font.SysFont('SimHei', 24)  # 得分的字体
    font2 = pygame.font.Font(None, 72)  # GAME OVER 的字体
    fwidth, fheight = font2.size('GAME OVER')

    # 如果蛇正在向右移动,那么快速点击向下向左,由于程序刷新没那么快,向下事件会被向左覆盖掉,导致蛇后退,直接GAME OVER
    # b 变量就是用于防止这种情况的发生
    b = True

    # 蛇
    snake = init\_snake()
    # 食物
    food = create\_food(snake)
    food\_style \= get\_food\_style()
    # 方向
    pos = (1, 0)

    game\_over \= True
    start \= False       # 是否开始,当start = True,game\_over = True 时,才显示 GAME OVER
    score = 0           # 得分
    orispeed = 0.5      # 原始速度
    speed = orispeed
    last\_move\_time \= None
    pause \= False       # 暂停

    while True:
        for event in pygame.event.get():
            if event.type == QUIT:
                sys.exit()
            elif event.type == KEYDOWN:
                if event.key == K\_RETURN:
                    if game\_over:
                        start \= True
                        game\_over \= False
                        b \= True
                        snake \= init\_snake()
                        food \= create\_food(snake)
                        food\_style \= get\_food\_style()
                        pos \= (1, 0)
                        # 得分
                        score = 0
                        last\_move\_time \= time.time()
                elif event.key == K\_SPACE:
                    if not game\_over:
                        pause \= not pause
                elif event.key in (K\_w, K\_UP):
                    # 这个判断是为了防止蛇向上移时按了向下键,导致直接 GAME OVER
                    if b and not pos\[1\]:
                        pos \= (0, -1)
                        b \= False
                elif event.key in (K\_s, K\_DOWN):
                    if b and not pos\[1\]:
                        pos \= (0, 1)
                        b \= False
                elif event.key in (K\_a, K\_LEFT):
                    if b and not pos\[0\]:
                        pos \= (-1, 0)
                        b \= False
                elif event.key in (K\_d, K\_RIGHT):
                    if b and not pos\[0\]:
                        pos \= (1, 0)
                        b \= False

        # 填充背景色
        screen.fill(BGCOLOR)
        # 画网格线 竖线
        for x in range(SIZE, SCREEN\_WIDTH, SIZE):
            pygame.draw.line(screen, BLACK, (x, SCOPE\_Y\[0\] \* SIZE), (x, SCREEN\_HEIGHT), LINE\_WIDTH)
        # 画网格线 横线
        for y in range(SCOPE\_Y\[0\] \* SIZE, SCREEN\_HEIGHT, SIZE):
            pygame.draw.line(screen, BLACK, (0, y), (SCREEN\_WIDTH, y), LINE\_WIDTH)

        if not game\_over:
            curTime \= time.time()
            if curTime - last\_move\_time > speed:
                if not pause:
                    b \= True
                    last\_move\_time \= curTime
                    next\_s \= (snake\[0\]\[0\] + pos\[0\], snake\[0\]\[1\] + pos\[1\])
                    if next\_s == food:
                        # 吃到了食物
                        snake.appendleft(next\_s)
                        score += food\_style\[0\]
                        speed \= orispeed - 0.03 \* (score // 100)
                        food \= create\_food(snake)
                        food\_style \= get\_food\_style()
                    else:
                        if SCOPE\_X\[0\] <= next\_s\[0\] <= SCOPE\_X\[1\] and SCOPE\_Y\[0\] <= next\_s\[1\] <= SCOPE\_Y\[1\] \\
                                and next\_s not in snake:
                            snake.appendleft(next\_s)
                            snake.pop()
                        else:
                            game\_over \= True

        # 画食物
        if not game\_over:
            # 避免 GAME OVER 的时候把 GAME OVER 的字给遮住了
            pygame.draw.rect(screen, food\_style\[1\], (food\[0\] \* SIZE, food\[1\] \* SIZE, SIZE, SIZE), 0)

        # 画蛇
        for s in snake:
            pygame.draw.rect(screen, DARK, (s\[0\] \* SIZE + LINE\_WIDTH, s\[1\] \* SIZE + LINE\_WIDTH,
                                            SIZE \- LINE\_WIDTH \* 2, SIZE - LINE\_WIDTH \* 2), 0)

        print\_text(screen, font1, 30, 7, f'速度: {score//100}')
        print\_text(screen, font1, 450, 7, f'得分: {score}')

        if game\_over:
            if start:
                print\_text(screen, font2, (SCREEN\_WIDTH \- fwidth) // 2, (SCREEN\_HEIGHT - fheight) // 2, 'GAME OVER', RED)

        pygame.display.update()

if \_\_name\_\_ == '\_\_main\_\_':
    main()
  • 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
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168

这里我为大家准备了一份针对零基础的Python学习资料,有兴趣的同学可以看看哦。

「 Python经验分享 」

学好 Python 不论是就业还是做副业赚钱都不错,但要学会 Python 还是要有一个学习规划。最后给大家免费分享一份全套的 Python 学习资料,给那些想学习 Python 的小伙伴们一点帮助!

一、Python所有方向的学习路线

Python所有方向路线就是把Python常用的技术点做整理,形成各个领域的知识点汇总,它的用处就在于,你可以按照上面的知识点去找对应的学习资源,保证自己学得较为全面。
9f49b566129f47b8a67243c1008edf79.png

二、学习软件

工欲善其事必先利其器。学习Python常用的开发软件都在这里了,给大家节省了很多时间。

8c4513c1a906b72cbf93031e6781512b.png

三、入门学习视频

我们在看视频学习的时候,不能光动眼动脑不动手,比较科学的学习方法是在理解之后运用它们,这时候练手项目就很适合了。

afc935d834c5452090670f48eda180e0.png

四、实战案例

光学理论是没用的,要学会跟着一起敲,要动手实操,才能将自己的所学运用到实际当中去,这时候可以搞点实战案例来学习。

252731a671c1fb70aad5355a2c5eeff0.png

五、面试资料

我们学习Python必然是为了找到高薪的工作,下面这些面试题是来自阿里、腾讯、字节等一线互联网大厂最新的面试资料,并且有阿里大佬给出了权威的解答,刷完这一套面试资料相信大家都能找到满意的工作。

6c361282296f86381401c05e862fe4e9.png

d2d978bb523c810abca3abe69e09bc1a.png

这份完整版的Python全套学习资料已经上传CSDN
朋友们如果需要可以微信扫描下方CSDN官方认证二维码免费领取【保证100%免费】。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/码创造者/article/detail/832538
推荐阅读
相关标签
  

闽ICP备14008679号