Python实现AI自动玩俄罗斯方块游戏

目录
  • 导语
  • 正文
    • 1)Tetris.py
    • 2)Tetris_model.py​​
    • 3)Tetris_ai.py​​
  • 效果展示

导语

提到《俄罗斯方块》(Tetris),那真是几乎无人不知无人不晓。​

其历史之悠久,可玩性之持久,能手轻轻一挥,吊打一大波游戏。

对于绝大多数小友而言,《俄罗斯方块》的规则根本无需多言——将形状不一的方块填满一行消除即可。

这款火了30几年的《俄罗斯方块》游戏之前就已经写过的哈,往期的Pygame合集里面可以找找看!

但今天木木子介绍的是《俄罗斯方块》的新作——实现AI自动玩儿游戏。

估计会让你三观尽毁,下巴掉落,惊呼:我玩了假游戏吧!

正文

移动、掉落、填充、消除!

木木子·你我的童年回忆《俄罗斯方块AI版本》已正式上线!

代码由三部分组成 Tetris.py、tetris_model.py 和 tetris_ai.py游戏的主要逻辑由 Tetis 控制,model 定义了方块的样式,AI 顾名思义实现了主要的 AI 算法。

1)Tetris.py

class Tetris(QMainWindow):
    def __init__(self):
        super().__init__()
        self.isStarted = False
        self.isPaused = False
        self.nextMove = None
        self.lastShape = Shape.shapeNone

        self.initUI()

    def initUI(self):
        self.gridSize = 22
        self.speed = 10

        self.timer = QBasicTimer()
        self.setFocusPolicy(Qt.StrongFocus)

        hLayout = QHBoxLayout()
        self.tboard = Board(self, self.gridSize)
        hLayout.addWidget(self.tboard)

        self.sidePanel = SidePanel(self, self.gridSize)
        hLayout.addWidget(self.sidePanel)

        self.statusbar = self.statusBar()
        self.tboard.msg2Statusbar[str].connect(self.statusbar.showMessage)

        self.start()

        self.center()
        self.setWindowTitle('AI俄罗斯方块儿')
        self.show()

        self.setFixedSize(self.tboard.width() + self.sidePanel.width(),
                          self.sidePanel.height() + self.statusbar.height())

    def center(self):
        screen = QDesktopWidget().screenGeometry()
        size = self.geometry()
        self.move((screen.width() - size.width()) // 2, (screen.height() - size.height()) // 2)

    def start(self):
        if self.isPaused:
            return

        self.isStarted = True
        self.tboard.score = 0
        BOARD_DATA.clear()

        self.tboard.msg2Statusbar.emit(str(self.tboard.score))

        BOARD_DATA.createNewPiece()
        self.timer.start(self.speed, self)

    def pause(self):
        if not self.isStarted:
            return

        self.isPaused = not self.isPaused

        if self.isPaused:
            self.timer.stop()
            self.tboard.msg2Statusbar.emit("paused")
        else:
            self.timer.start(self.speed, self)

        self.updateWindow()

    def updateWindow(self):
        self.tboard.updateData()
        self.sidePanel.updateData()
        self.update()

    def timerEvent(self, event):
        if event.timerId() == self.timer.timerId():
            if TETRIS_AI and not self.nextMove:
                self.nextMove = TETRIS_AI.nextMove()
            if self.nextMove:
                k = 0
                while BOARD_DATA.currentDirection != self.nextMove[0] and k < 4:
                    BOARD_DATA.rotateRight()
                    k += 1
                k = 0
                while BOARD_DATA.currentX != self.nextMove[1] and k < 5:
                    if BOARD_DATA.currentX > self.nextMove[1]:
                        BOARD_DATA.moveLeft()
                    elif BOARD_DATA.currentX < self.nextMove[1]:
                        BOARD_DATA.moveRight()
                    k += 1
            # lines = BOARD_DATA.dropDown()
            lines = BOARD_DATA.moveDown()
            self.tboard.score += lines
            if self.lastShape != BOARD_DATA.currentShape:
                self.nextMove = None
                self.lastShape = BOARD_DATA.currentShape
            self.updateWindow()
        else:
            super(Tetris, self).timerEvent(event)

    def keyPressEvent(self, event):
        if not self.isStarted or BOARD_DATA.currentShape == Shape.shapeNone:
            super(Tetris, self).keyPressEvent(event)
            return

        key = event.key()

        if key == Qt.Key_P:
            self.pause()
            return

        if self.isPaused:
            return
        elif key == Qt.Key_Left:
            BOARD_DATA.moveLeft()
        elif key == Qt.Key_Right:
            BOARD_DATA.moveRight()
        elif key == Qt.Key_Up:
            BOARD_DATA.rotateLeft()
        elif key == Qt.Key_Space:
            self.tboard.score += BOARD_DATA.dropDown()
        else:
            super(Tetris, self).keyPressEvent(event)

        self.updateWindow()

def drawSquare(painter, x, y, val, s):
    colorTable = [0x000000, 0xCC6666, 0x66CC66, 0x6666CC,
                  0xCCCC66, 0xCC66CC, 0x66CCCC, 0xDAAA00]

    if val == 0:
        return

    color = QColor(colorTable[val])
    painter.fillRect(x + 1, y + 1, s - 2, s - 2, color)

    painter.setPen(color.lighter())
    painter.drawLine(x, y + s - 1, x, y)
    painter.drawLine(x, y, x + s - 1, y)

    painter.setPen(color.darker())
    painter.drawLine(x + 1, y + s - 1, x + s - 1, y + s - 1)
    painter.drawLine(x + s - 1, y + s - 1, x + s - 1, y + 1)

class SidePanel(QFrame):
    def __init__(self, parent, gridSize):
        super().__init__(parent)
        self.setFixedSize(gridSize * 5, gridSize * BOARD_DATA.height)
        self.move(gridSize * BOARD_DATA.width, 0)
        self.gridSize = gridSize

    def updateData(self):
        self.update()

    def paintEvent(self, event):
        painter = QPainter(self)
        minX, maxX, minY, maxY = BOARD_DATA.nextShape.getBoundingOffsets(0)

        dy = 3 * self.gridSize
        dx = (self.width() - (maxX - minX) * self.gridSize) / 2

        val = BOARD_DATA.nextShape.shape
        for x, y in BOARD_DATA.nextShape.getCoords(0, 0, -minY):
            drawSquare(painter, x * self.gridSize + dx, y * self.gridSize + dy, val, self.gridSize)

class Board(QFrame):
    msg2Statusbar = pyqtSignal(str)
    speed = 10

    def __init__(self, parent, gridSize):
        super().__init__(parent)
        self.setFixedSize(gridSize * BOARD_DATA.width, gridSize * BOARD_DATA.height)
        self.gridSize = gridSize
        self.initBoard()

    def initBoard(self):
        self.score = 0
        BOARD_DATA.clear()

    def paintEvent(self, event):
        painter = QPainter(self)

        # Draw backboard
        for x in range(BOARD_DATA.width):
            for y in range(BOARD_DATA.height):
                val = BOARD_DATA.getValue(x, y)
                drawSquare(painter, x * self.gridSize, y * self.gridSize, val, self.gridSize)

        # Draw current shape
        for x, y in BOARD_DATA.getCurrentShapeCoord():
            val = BOARD_DATA.currentShape.shape
            drawSquare(painter, x * self.gridSize, y * self.gridSize, val, self.gridSize)

        # Draw a border
        painter.setPen(QColor(0x777777))
        painter.drawLine(self.width()-1, 0, self.width()-1, self.height())
        painter.setPen(QColor(0xCCCCCC))
        painter.drawLine(self.width(), 0, self.width(), self.height())

    def updateData(self):
        self.msg2Statusbar.emit(str(self.score))
        self.update()

if __name__ == '__main__':
    # random.seed(32)
    app = QApplication([])
    tetris = Tetris()
    sys.exit(app.exec_())

2)Tetris_model.py​​

import random

class Shape(object):
    shapeNone = 0
    shapeI = 1
    shapeL = 2
    shapeJ = 3
    shapeT = 4
    shapeO = 5
    shapeS = 6
    shapeZ = 7

    shapeCoord = (
        ((0, 0), (0, 0), (0, 0), (0, 0)),
        ((0, -1), (0, 0), (0, 1), (0, 2)),
        ((0, -1), (0, 0), (0, 1), (1, 1)),
        ((0, -1), (0, 0), (0, 1), (-1, 1)),
        ((0, -1), (0, 0), (0, 1), (1, 0)),
        ((0, 0), (0, -1), (1, 0), (1, -1)),
        ((0, 0), (0, -1), (-1, 0), (1, -1)),
        ((0, 0), (0, -1), (1, 0), (-1, -1))
    )

    def __init__(self, shape=0):
        self.shape = shape

    def getRotatedOffsets(self, direction):
        tmpCoords = Shape.shapeCoord[self.shape]
        if direction == 0 or self.shape == Shape.shapeO:
            return ((x, y) for x, y in tmpCoords)

        if direction == 1:
            return ((-y, x) for x, y in tmpCoords)

        if direction == 2:
            if self.shape in (Shape.shapeI, Shape.shapeZ, Shape.shapeS):
                return ((x, y) for x, y in tmpCoords)
            else:
                return ((-x, -y) for x, y in tmpCoords)

        if direction == 3:
            if self.shape in (Shape.shapeI, Shape.shapeZ, Shape.shapeS):
                return ((-y, x) for x, y in tmpCoords)
            else:
                return ((y, -x) for x, y in tmpCoords)

    def getCoords(self, direction, x, y):
        return ((x + xx, y + yy) for xx, yy in self.getRotatedOffsets(direction))

    def getBoundingOffsets(self, direction):
        tmpCoords = self.getRotatedOffsets(direction)
        minX, maxX, minY, maxY = 0, 0, 0, 0
        for x, y in tmpCoords:
            if minX > x:
                minX = x
            if maxX < x:
                maxX = x
            if minY > y:
                minY = y
            if maxY < y:
                maxY = y
        return (minX, maxX, minY, maxY)

class BoardData(object):
    width = 10
    height = 22

    def __init__(self):
        self.backBoard = [0] * BoardData.width * BoardData.height

        self.currentX = -1
        self.currentY = -1
        self.currentDirection = 0
        self.currentShape = Shape()
        self.nextShape = Shape(random.randint(1, 7))

        self.shapeStat = [0] * 8

    def getData(self):
        return self.backBoard[:]

    def getValue(self, x, y):
        return self.backBoard[x + y * BoardData.width]

    def getCurrentShapeCoord(self):
        return self.currentShape.getCoords(self.currentDirection, self.currentX, self.currentY)

    def createNewPiece(self):
        minX, maxX, minY, maxY = self.nextShape.getBoundingOffsets(0)
        result = False
        if self.tryMoveCurrent(0, 5, -minY):
            self.currentX = 5
            self.currentY = -minY
            self.currentDirection = 0
            self.currentShape = self.nextShape
            self.nextShape = Shape(random.randint(1, 7))
            result = True
        else:
            self.currentShape = Shape()
            self.currentX = -1
            self.currentY = -1
            self.currentDirection = 0
            result = False
        self.shapeStat[self.currentShape.shape] += 1
        return result

    def tryMoveCurrent(self, direction, x, y):
        return self.tryMove(self.currentShape, direction, x, y)

    def tryMove(self, shape, direction, x, y):
        for x, y in shape.getCoords(direction, x, y):
            if x >= BoardData.width or x < 0 or y >= BoardData.height or y < 0:
                return False
            if self.backBoard[x + y * BoardData.width] > 0:
                return False
        return True

    def moveDown(self):
        lines = 0
        if self.tryMoveCurrent(self.currentDirection, self.currentX, self.currentY + 1):
            self.currentY += 1
        else:
            self.mergePiece()
            lines = self.removeFullLines()
            self.createNewPiece()
        return lines

    def dropDown(self):
        while self.tryMoveCurrent(self.currentDirection, self.currentX, self.currentY + 1):
            self.currentY += 1
        self.mergePiece()
        lines = self.removeFullLines()
        self.createNewPiece()
        return lines

    def moveLeft(self):
        if self.tryMoveCurrent(self.currentDirection, self.currentX - 1, self.currentY):
            self.currentX -= 1

    def moveRight(self):
        if self.tryMoveCurrent(self.currentDirection, self.currentX + 1, self.currentY):
            self.currentX += 1

    def rotateRight(self):
        if self.tryMoveCurrent((self.currentDirection + 1) % 4, self.currentX, self.currentY):
            self.currentDirection += 1
            self.currentDirection %= 4

    def rotateLeft(self):
        if self.tryMoveCurrent((self.currentDirection - 1) % 4, self.currentX, self.currentY):
            self.currentDirection -= 1
            self.currentDirection %= 4

    def removeFullLines(self):
        newBackBoard = [0] * BoardData.width * BoardData.height
        newY = BoardData.height - 1
        lines = 0
        for y in range(BoardData.height - 1, -1, -1):
            blockCount = sum([1 if self.backBoard[x + y * BoardData.width] > 0 else 0 for x in range(BoardData.width)])
            if blockCount < BoardData.width:
                for x in range(BoardData.width):
                    newBackBoard[x + newY * BoardData.width] = self.backBoard[x + y * BoardData.width]
                newY -= 1
            else:
                lines += 1
        if lines > 0:
            self.backBoard = newBackBoard
        return lines

    def mergePiece(self):
        for x, y in self.currentShape.getCoords(self.currentDirection, self.currentX, self.currentY):
            self.backBoard[x + y * BoardData.width] = self.currentShape.shape

        self.currentX = -1
        self.currentY = -1
        self.currentDirection = 0
        self.currentShape = Shape()

    def clear(self):
        self.currentX = -1
        self.currentY = -1
        self.currentDirection = 0
        self.currentShape = Shape()
        self.backBoard = [0] * BoardData.width * BoardData.height

BOARD_DATA = BoardData()

3)Tetris_ai.py​​

from tetris_model import BOARD_DATA, Shape
import math
from datetime import datetime
import numpy as np

class TetrisAI(object):

    def nextMove(self):
        t1 = datetime.now()
        if BOARD_DATA.currentShape == Shape.shapeNone:
            return None

        currentDirection = BOARD_DATA.currentDirection
        currentY = BOARD_DATA.currentY
        _, _, minY, _ = BOARD_DATA.nextShape.getBoundingOffsets(0)
        nextY = -minY

        # print("=======")
        strategy = None
        if BOARD_DATA.currentShape.shape in (Shape.shapeI, Shape.shapeZ, Shape.shapeS):
            d0Range = (0, 1)
        elif BOARD_DATA.currentShape.shape == Shape.shapeO:
            d0Range = (0,)
        else:
            d0Range = (0, 1, 2, 3)

        if BOARD_DATA.nextShape.shape in (Shape.shapeI, Shape.shapeZ, Shape.shapeS):
            d1Range = (0, 1)
        elif BOARD_DATA.nextShape.shape == Shape.shapeO:
            d1Range = (0,)
        else:
            d1Range = (0, 1, 2, 3)

        for d0 in d0Range:
            minX, maxX, _, _ = BOARD_DATA.currentShape.getBoundingOffsets(d0)
            for x0 in range(-minX, BOARD_DATA.width - maxX):
                board = self.calcStep1Board(d0, x0)
                for d1 in d1Range:
                    minX, maxX, _, _ = BOARD_DATA.nextShape.getBoundingOffsets(d1)
                    dropDist = self.calcNextDropDist(board, d1, range(-minX, BOARD_DATA.width - maxX))
                    for x1 in range(-minX, BOARD_DATA.width - maxX):
                        score = self.calculateScore(np.copy(board), d1, x1, dropDist)
                        if not strategy or strategy[2] < score:
                            strategy = (d0, x0, score)
        print("===", datetime.now() - t1)
        return strategy

    def calcNextDropDist(self, data, d0, xRange):
        res = {}
        for x0 in xRange:
            if x0 not in res:
                res[x0] = BOARD_DATA.height - 1
            for x, y in BOARD_DATA.nextShape.getCoords(d0, x0, 0):
                yy = 0
                while yy + y < BOARD_DATA.height and (yy + y < 0 or data[(y + yy), x] == Shape.shapeNone):
                    yy += 1
                yy -= 1
                if yy < res[x0]:
                    res[x0] = yy
        return res

    def calcStep1Board(self, d0, x0):
        board = np.array(BOARD_DATA.getData()).reshape((BOARD_DATA.height, BOARD_DATA.width))
        self.dropDown(board, BOARD_DATA.currentShape, d0, x0)
        return board

    def dropDown(self, data, shape, direction, x0):
        dy = BOARD_DATA.height - 1
        for x, y in shape.getCoords(direction, x0, 0):
            yy = 0
            while yy + y < BOARD_DATA.height and (yy + y < 0 or data[(y + yy), x] == Shape.shapeNone):
                yy += 1
            yy -= 1
            if yy < dy:
                dy = yy
        # print("dropDown: shape {0}, direction {1}, x0 {2}, dy {3}".format(shape.shape, direction, x0, dy))
        self.dropDownByDist(data, shape, direction, x0, dy)

    def dropDownByDist(self, data, shape, direction, x0, dist):
        for x, y in shape.getCoords(direction, x0, 0):
            data[y + dist, x] = shape.shape

    def calculateScore(self, step1Board, d1, x1, dropDist):
        # print("calculateScore")
        t1 = datetime.now()
        width = BOARD_DATA.width
        height = BOARD_DATA.height

        self.dropDownByDist(step1Board, BOARD_DATA.nextShape, d1, x1, dropDist[x1])
        # print(datetime.now() - t1)

        # Term 1: lines to be removed
        fullLines, nearFullLines = 0, 0
        roofY = [0] * width
        holeCandidates = [0] * width
        holeConfirm = [0] * width
        vHoles, vBlocks = 0, 0
        for y in range(height - 1, -1, -1):
            hasHole = False
            hasBlock = False
            for x in range(width):
                if step1Board[y, x] == Shape.shapeNone:
                    hasHole = True
                    holeCandidates[x] += 1
                else:
                    hasBlock = True
                    roofY[x] = height - y
                    if holeCandidates[x] > 0:
                        holeConfirm[x] += holeCandidates[x]
                        holeCandidates[x] = 0
                    if holeConfirm[x] > 0:
                        vBlocks += 1
            if not hasBlock:
                break
            if not hasHole and hasBlock:
                fullLines += 1
        vHoles = sum([x ** .7 for x in holeConfirm])
        maxHeight = max(roofY) - fullLines
        # print(datetime.now() - t1)

        roofDy = [roofY[i] - roofY[i+1] for i in range(len(roofY) - 1)]

        if len(roofY) <= 0:
            stdY = 0
        else:
            stdY = math.sqrt(sum([y ** 2 for y in roofY]) / len(roofY) - (sum(roofY) / len(roofY)) ** 2)
        if len(roofDy) <= 0:
            stdDY = 0
        else:
            stdDY = math.sqrt(sum([y ** 2 for y in roofDy]) / len(roofDy) - (sum(roofDy) / len(roofDy)) ** 2)

        absDy = sum([abs(x) for x in roofDy])
        maxDy = max(roofY) - min(roofY)
        # print(datetime.now() - t1)

        score = fullLines * 1.8 - vHoles * 1.0 - vBlocks * 0.5 - maxHeight ** 1.5 * 0.02 \
            - stdY * 0.0 - stdDY * 0.01 - absDy * 0.2 - maxDy * 0.3
        # print(score, fullLines, vHoles, vBlocks, maxHeight, stdY, stdDY, absDy, roofY, d0, x0, d1, x1)
        return score

TETRIS_AI = TetrisAI()

效果展示

1)视频展示——

【普通玩家VS高手玩家】一带传奇游戏《俄罗斯方块儿》AI版!

2)截图展示——

以上就是Python实现AI自动玩俄罗斯方块游戏的详细内容,更多关于Python俄罗斯方块的资料请关注我们其它相关文章!

(0)

相关推荐

  • python实现俄罗斯方块小游戏

    回顾我们的python制作小游戏之路,几篇非常精彩的文章 我们用python实现了坦克大战 python制作坦克大战 我们用python实现了飞船大战 python制作飞船大战 我们用python实现了两种不同的贪吃蛇游戏 200行python代码实现贪吃蛇游戏 150行代码实现贪吃蛇游戏 我们用python实现了扫雷游戏 python实现扫雷游戏 我们用python实现了五子棋游戏 python实现五子棋游戏 今天我们用python来实现小时候玩过的俄罗斯方块游戏吧 具体代码与文件可以访问我的

  • python如何写个俄罗斯方块

    俄罗斯方块是俄罗斯人发明的一款休闲类的小游戏,这款小游戏可以说是很多人童年的主打电子游戏了,本文我们使用 Python 来实现这款小游戏. 游戏的基本规则是:移动.旋转和摆放游戏自动输出的各种方块,使之排列成完整的一行或多行并且消除得分. 实现 我们实现俄罗斯方块,主要用到的是 PyQt5 库,安装使用 pip install PyQt5 即可,游戏的组成比较简单,主要包括:主界面.各种方块和计分板,下面我们来看一下具体实现. 首先,我们来画一个主界面,主要实现代码如下: class MainB

  • python编写俄罗斯方块

    本文实例为大家分享了python实现俄罗斯方块的具体代码,供大家参考,具体内容如下 #coding=utf-8 from tkinter import * from random import * import threading from tkinter.messagebox import showinfo from tkinter.messagebox import askquestion import threading from time import sleep class Brick

  • python实现俄罗斯方块游戏(改进版)

    本文为大家分享了python实现俄罗斯方块游戏,继上一篇的改进版,供大家参考,具体内容如下 1.加了方块预览部分 2.加了开始按钮 在公司实习抽空写的,呵呵.觉得Python还不错,以前觉得像个玩具语言.希望能够用它做更多大事吧!!!加油. 截图如下: 代码如下: #coding=utf-8 from Tkinter import *; from random import *; import thread; from tkMessageBox import showinfo; import t

  • python 基于pygame实现俄罗斯方块

    一.简单说明 80.90后的小伙伴都玩过"俄罗斯方块",那种"叱咤风云"场景 偶尔闪现在脑海 真的是太爽了:如果没有来得及玩过的同学,这次可以真正的自己做一个了 本实例用的是Python3(当然了Python3.5 3.6 3.7....都行 )+ pygame实现的 运行之前需要安装pygame模块,安装命令如下 pip install pygame -i https://mirrors.aliyun.com/pypi/simple/ 二.运行效果 三.完整代码

  • python实现简单俄罗斯方块

    本文实例为大家分享了python实现俄罗斯方块的具体代码,供大家参考,具体内容如下 # teris.py # A module for game teris. # By programmer FYJ from tkinter import * from time import sleep from random import * from tkinter import messagebox class Teris: def __init__(self): #方块颜色列表 self.color =

  • Python实现AI自动玩俄罗斯方块游戏

    目录 导语 正文 1)Tetris.py 2)Tetris_model.py​​ 3)Tetris_ai.py​​ 效果展示 导语 提到<俄罗斯方块>(Tetris),那真是几乎无人不知无人不晓.​ 其历史之悠久,可玩性之持久,能手轻轻一挥,吊打一大波游戏. 对于绝大多数小友而言,<俄罗斯方块>的规则根本无需多言——将形状不一的方块填满一行消除即可. 这款火了30几年的<俄罗斯方块>游戏之前就已经写过的哈,往期的Pygame合集里面可以找找看! 但今天木木子介绍的是&l

  • 用Python编写一个简单的俄罗斯方块游戏的教程

    俄罗斯方块游戏,使用Python实现,总共有350+行代码,实现了俄罗斯方块游戏的基本功能,同时会记录所花费时间,消去的总行数,所得的总分,还包括一个排行榜,可以查看最高记录. 排行榜中包含一系列的统计功能,如单位时间消去的行数,单位时间得分等. 附源码: from Tkinter import * from tkMessageBox import * import random import time #俄罗斯方块界面的高度 HEIGHT = 18 #俄罗斯方块界面的宽度 WIDTH = 10

  • python和pygame实现简单俄罗斯方块游戏

    本文为大家分享了python实现俄罗斯方块游戏的具体代码,供大家参考,具体内容如下 Github:Tetris 代码: # -*- coding:utf-8 -*- import pygame, sys, random, copy from pygame.locals import * pygame.init() CubeWidth = 40 CubeHeight = 40 Column = 10 Row = 20 ScreenWidth = CubeWidth * (Column + 5) S

  • Python实现AI自动抠图实例解析

    一.简介 抠图是用PS? 用魔棒和快速选择工具? 遇到复杂背景怎么办? 最近发现一个神奇的工具--Remove Image Background https://www.remove.bg/zh 它是基于Python.Ruby和深度学习技术开发,通过强大的AI人工智能算法实现自动识别出前景主体与背景图,秒秒种完成抠图. 这款抠图工具有两种简单方式: 1.在线抠图 2.API代码抠图 二.在线抠图 1.打开remove.bg网站首页,可以上传本地图片,也可以选择网络图片的URL链接. 2.上传几秒

  • Python使用pygame模块编写俄罗斯方块游戏的代码实例

    文章先介绍了关于俄罗斯方块游戏的几个术语. 边框--由10*20个空格组成,方块就落在这里面. 盒子--组成方块的其中小方块,是组成方块的基本单元. 方块--从边框顶掉下的东西,游戏者可以翻转和改变位置.每个方块由4个盒子组成. 形状--不同类型的方块.这里形状的名字被叫做T, S, Z ,J, L, I , O.如下图所示: 模版--用一个列表存放形状被翻转后的所有可能样式.全部存放在变量里,变量名字如S_SHAPE_TEMPLATE or J_SHAPE_TEMPLATE 着陆--当一个方块

  • pygame实现俄罗斯方块游戏(AI篇1)

    上次更新到pygame实现俄罗斯方块游戏(基础篇3) 现在继续 一.定义玩家类 定义玩家类是为了便于进行手动和机器模式或各种不同机器人模式的混合使用,增加代码扩展性. 可以先定义一个玩家基类 class Player(object): auto_mode=False # 是否是自动模式,自动模式应当不响应键盘操作 def __init__(self): pass def run(self): # 进行操作 pass 手动类和机器类继承自Player类 class HumanPlayer(Play

  • pygame实现俄罗斯方块游戏(AI篇2)

    继续pygame实现俄罗斯方块游戏(AI篇1)的代码更新 一.消除后才做评价 上一篇我们是对方块落下的位置和落下后出来的空洞进行了评价,但是这些评价都是没有计算消除的,以至于机器人现在不会考虑去进行那些完全不会留下空洞的消除,比如下面这种消除. 但我们知道这种消除是不会产生空洞的. 所以我们要在计算评价的时候最好计算消除以后的评价. 我们只要在Matrix的函数里加一个do_clear函数来进行消除 def do_clear(self): for i in range(self.rows-1,-

  • Python还能这么玩之用Python做个小游戏的外挂

    一.前言 我打开4399小游戏网,点开了一个不知名的游戏,唔,做寿司的,有材料在一边,客人过来后说出他们的要求,你按照菜单做好端给他便好~要怎么实现他自动做菜呢? 二.工具的准备 需要安装autopy和PIL以及pywin32包. 1.截屏和图像处理工具 截屏是获取游戏图像以供分析游戏提示,其实没有专门的工具直接Print Screen粘贴到图像处理工具里也可以.我用的是PicPick,相当好用,而且个人用户是免费的,而图像处理则是为了获取各种信息的,我们要用它得到点菜图像后保存起来,供外挂分析

  • Python实现简单的俄罗斯方块游戏

    本文实例为大家分享了Python实现俄罗斯方块游戏的具体代码,供大家参考,具体内容如下 玩法:童年经典,普通模式没啥意思,小时候我们都是玩加速的. 源码分享: import os import sys import random from modules import * from PyQt5.QtGui import * from PyQt5.QtCore import * from PyQt5.QtWidgets import * '''定义俄罗斯方块游戏类''' class TetrisG

  • Python实现自动玩贪吃蛇程序

    目录 实现效果 代码 实现效果 先看看效果 这比我手动的快多了,而且是单机的,自动玩没惹骂我,哈哈 ,多人游戏整个自动玩会被骂死~ 代码 没装软件的先安装一下软件,没装模块的安装一下pygame模块. pip install pygame 导入模块 import pygame,sys,time,random from pygame.locals import * 定义颜色变量 redColour = pygame.Color(255,0,0) blackColour = pygame.Color

随机推荐