iis服务器助手广告广告
返回顶部
首页 > 资讯 > 后端开发 > Python >Python实现AI自动玩俄罗斯方块游戏
  • 265
分享到

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

2024-04-02 19:04:59 265人浏览 八月长安

Python 官方文档:入门教程 => 点击学习

摘要

目录导语正文1)Tetris.py2)Tetris_model.py​​3)Tetris_ai.py​​效果展示导语 提到《俄罗斯方块》(Tetris),那真是几乎无人不知无人不晓。

导语

提到《俄罗斯方块》(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俄罗斯方块的资料请关注编程网其它相关文章!

--结束END--

本文标题: Python实现AI自动玩俄罗斯方块游戏

本文链接: https://www.lsjlt.com/news/142939.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • Python实现AI自动玩俄罗斯方块游戏
    目录导语正文1)Tetris.py2)Tetris_model.py​​3)Tetris_ai.py​​效果展示导语 提到《俄罗斯方块》(Tetris),那真是几乎无人不知无人不晓。...
    99+
    2024-04-02
  • python实现简单俄罗斯方块游戏
    本文实例为大家分享了python实现简单俄罗斯方块游戏的具体代码,供大家参考,具体内容如下 import pygame,sys,random,time all_block = [[...
    99+
    2024-04-02
  • C++实现俄罗斯方块小游戏
    本文实例为大家分享了C++实现俄罗斯方块小游戏的具体代码,供大家参考,具体内容如下 操作说明: D F:左右旋转 J  L:左右移动 E(一堆键都行): 加快下落速度 空格...
    99+
    2024-04-02
  • C/C++实现俄罗斯方块游戏
    目录一、游戏效果展示二、完整代码三、所需开发环境四、具体项目实现①游戏欢迎界面 welcome( )②游戏背景 initGameScreen( ) ③方块表示 int bl...
    99+
    2024-04-02
  • JavaScript canvas实现俄罗斯方块游戏
    俄罗斯方块是个很经典的小游戏,也尝试写了一下。不过我想用尽量简洁逻辑清晰的代码实现。不用过多的代码记录下落方块的模型,或者记录每一个下落方块的x,y。想了下面的思路,然后发现这样很写...
    99+
    2024-04-02
  • pygame俄罗斯方块游戏
    俄罗斯方块游戏开发 俄罗斯方块是一款世界级经典游戏,每门语言开发学习初步都会考虑制作俄罗斯方块游戏今天带着大家把俄罗斯方块用python语言开发一次 开发准备 安装python 2.引入游戏库pyga...
    99+
    2023-10-25
    pygame 游戏 python
  • Python实现简单的俄罗斯方块游戏
    本文实例为大家分享了Python实现俄罗斯方块游戏的具体代码,供大家参考,具体内容如下 玩法:童年经典,普通模式没啥意思,小时候我们都是玩加速的。 源码分享: import o...
    99+
    2024-04-02
  • 基于Matlab实现俄罗斯方块游戏
    我最早写的一个matlab小游戏 写的可能不够简洁,但还有可玩性, 先发上来,以后可能改进或出教程。 大家自己探索吧(外挂是哪个按键,更改颜色是哪个按键) 游戏效果 完整代码 fu...
    99+
    2024-04-02
  • c++实现俄罗斯方块游戏代码
    俄罗斯方块c++ 1.创建项目2.总共需要创建两个文件,一个main.cpp,一个是elsfk2.h。本人使用的编译器是vs2019. 3.在项目的源文件夹下创建一个文件夹image...
    99+
    2024-04-02
  • c++如何实现俄罗斯方块游戏
    这篇文章主要介绍“c++如何实现俄罗斯方块游戏”,在日常操作中,相信很多人在c++如何实现俄罗斯方块游戏问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”c++如何实现俄罗斯方块游戏”的疑惑有所帮助!接下来,请跟...
    99+
    2023-06-22
  • Java实现经典俄罗斯方块游戏
    目录前言主要设计功能截图代码实现总结前言 俄罗斯方块是一个最初由阿列克谢帕吉特诺夫在苏联设计和编程的益智类视频游戏。 《俄罗斯方块》的基本规则是移动、旋转和摆放游戏自动输出的各种方块...
    99+
    2024-04-02
  • Python完整实现俄罗斯方块游戏全解
    目录1俄罗斯方块游戏2Python代码实现 2.1展现2.2Python代码1 俄罗斯方块游戏 《俄罗斯方块》原本是前苏联科学家阿列克谢·帕基特诺夫所开发的教...
    99+
    2024-04-02
  • Python+Pygame实战之俄罗斯方块游戏的实现
    目录导语一、运行环境二、代码展示三、效果展示导语 俄罗斯方块,作为是一款家喻户晓的游戏,陪伴70、80甚至90后,度过无忧的儿时岁月 它上手简单能自由组合、拼接技巧也很多。 你知道么...
    99+
    2022-12-28
    Python Pygame俄罗斯方块游戏 Python 俄罗斯方块 Python Pygame 游戏
  • C#游戏开发之实现俄罗斯方块游戏
    目录实践过程效果代码实践过程 效果 代码 public partial class Form1 : Form { public Form1() { ...
    99+
    2023-01-05
    C#俄罗斯方块游戏 C#俄罗斯方块 C# 游戏
  • 使用JS+CSS实现俄罗斯方块游戏
    目录前提:设置HTML结构:创建CSS样式:编写JavaScript代码:响应式设计:添加触摸事件支持:测试并优化:代码示例:前提: 要在网页上实现一个适用于PC端和移动端的俄罗斯方...
    99+
    2023-05-14
    JS+CSS JS+CSS实现俄罗斯方块
  • 基于Python实现俄罗斯方块躲闪小游戏
    俄罗斯方块是一款经典的益智游戏,最早由俄罗斯人阿列克谢·帕基特诺夫在1984年开发。据说他的灵感来自于儿时拼积木的经历。这款游戏最初在苏联的计算机上流行开来,后来又在世...
    99+
    2023-05-15
    Python俄罗斯方块躲闪游戏 Python方块躲闪游戏 Python 游戏
  • 怎么用Javascript实现俄罗斯方块游戏
    这篇文章主要介绍“怎么用Javascript实现俄罗斯方块游戏”,在日常操作中,相信很多人在怎么用Javascript实现俄罗斯方块游戏问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大...
    99+
    2024-04-02
  • Java实现俄罗斯方块游戏简单版
    本文实例为大家分享了Java实现俄罗斯方块游戏的具体代码,供大家参考,具体内容如下 游戏页面效果如下: 俄罗斯方块游戏本身的逻辑: 俄罗斯方块游戏的逻辑是比较简单的。它就类似于堆砌...
    99+
    2024-04-02
  • Java实现俄罗斯方块小游戏源码
    本文实例为大家分享了Java实现俄罗斯方块小游戏的具体代码,供大家参考,具体内容如下 一、最终效果 二、功能需求 1、 在二维平面里面用各种随机产生的方块堆积木,每满一行消去一行,...
    99+
    2024-04-02
  • python是怎么实现简单俄罗斯方块游戏
    本篇文章为大家展示了python是怎么实现简单俄罗斯方块游戏,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。Python的优点有哪些1、简单易用,与C/C++、Java、C# 等传统语言相比,Pyth...
    99+
    2023-06-26
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作