猫史档案馆


【Python作品分享】黑白翻转棋【作品秀】

用户:纯棉生活纯棉生活查看:0 回复:0 评论:0 创建时间:2022-06-25T15:25:04


【作品展示】

center_image

 

【作品介绍】

这是一款非常烧脑的游戏,你需要通过翻转对方的棋子来让自己的棋子尽可能地多。

本作品灵感源于黑白翻转棋的实体游戏棋,但那种不够烧脑。我做的这款,可是你一个人和电脑PK的哦!

本作品参照了一本Python游戏书的代码,加以自己的创作,完成了这个作品。目前仍有一小部分Bug未解决,但基本不影响游戏体验。

准备好了吗?一起烧脑吧!

 

【作品源代码】

import random
import sys
SIZE = 8
WIDTH,HEIGHT = SIZE,SIZE

def PrintRules():
    print('''以下是游戏规则:
· 翻转:
    只要两个自己的棋子夹住了对方的棋子,就可以把对方的棋子翻过来。
    
    例如:
         12345678
        +--------+
       1|    X X |1
       2|    OO  |2
       3|XOOOG   |3
       4|  OOX   |4
       5|  OXX   |5
    上图中,持棋子X的玩家在G处落子后,将会形成如下的样子:
         12345678
        +--------+
       1|    X X |1
       2|    XX  |2
       3|XXXXX   |3
       4|  OOX   |4
       5|  OXX   |5
    
    注意:夹住对方棋子的己方棋子,其中一个一定要是刚刚下的。
        
按下回车键来继续...''')
    input()
    print('''· 落子:
    每次落子必须可以翻转对方的至少一个棋子。
    
    例如:
         12345678
        +--------+
        1|    X X |1
        2|    OO  |2
        3|XOOOa   |3
        4|  OOb   |4
        5|  OXX   |5
    上图中,持棋子X的玩家可以下在a处,但不能下在b处。
    
    注意:如果当前玩家无法放置棋子,则轮到下一位玩家;
         如果两名玩家都不能放置棋子,则游戏结束;
         如果棋盘满了,游戏也结束。
                
按下回车键来继续...''')
    input()
    print('''· 游戏目标:
    在游戏结束后,谁的棋子数多,谁就获胜。
    
    例如:
        12345678
       +--------+
      1|XXOOOXOO|1
      2|XOXOOXOO|2
      3|OXOOOXOX|3
      4|OXOOXOOO|4
      5|XXXOOXOX|5
      6|OOXOXXXO|6
      7|XXXXOXOO|7
      8|OOXOOXXX|8
       +--------+
        12345678
        
    上图中有29个棋子X和35个棋子O,所以持棋子O的玩家获胜。
    
如果你已经了解了游戏规则,那么可以按下回车键来开始和电脑的对决了!''')
    input()


def DrawBoard(board):
    # 打印游戏板
    a='  '
    for i in range(WIDTH):
        a += str(i+1)
        a += ' '
    print(a)
    print(' +{}'.format('-+' * (WIDTH)))
    for y in range(HEIGHT):
        print('{}|{}|{}'.format(y + 1, '|'.join(board[y]), y + 1))
        print(' +{}'.format('-+' * (WIDTH)))
    print(a)


def GetNewBoard():
    # 创建一个新的游戏板
    board = []
    for i in range(HEIGHT):
        board.append([' '] * WIDTH)
    return board

def IsValidMove(board,mark,xstart,ystart):
    # 返回可翻转列表,如果没有棋子可翻转,则返回False
    if board[xstart][ystart] != ' ' or not IsOnBoard(xstart,ystart):
        return False

    if mark == 'X':
        OtherMark = 'O'
    else:
        OtherMark = 'X'

    TilesToFilp = []
    for xdir,ydir in [[0,1],[1,1],[1,0],[1,-1],[0,-1],[-1,-1],[-1,0],[-1,1]]:
        x,y = xstart,ystart
        x += xdir
        y += ydir
        while IsOnBoard(x,y) and board[x][y] == OtherMark:
            x += xdir
            y += ydir
            if IsOnBoard(x,y) and board[x][y] == mark:
                while True:
                    x -= xdir
                    y -= ydir
                    if x == xstart and y == ystart:
                        break
                    TilesToFilp.append([x,y])

    if len(TilesToFilp) == 0:
        return False
    return TilesToFilp

def IsOnBoard(x,y):
    # 返回(x,y)是否在棋盘上
    return 0 <= x <= WIDTH - 1 and 0 <= y <= HEIGHT-1

def GetBoardWithValidMoves(board,mark):
    BoardCopy = GetBoardCopy(board)

    for x,y in GetValidMoves(BoardCopy,mark):
        BoardCopy[x][y] = '.'
    return BoardCopy

def GetValidMoves(board,mark):
    ValidMoves = []
    for x in range(WIDTH):
        for y in range(HEIGHT):
            if IsValidMove(board,mark,x,y) != False:
                ValidMoves.append([x,y])
    return ValidMoves

def GetPlayerMark():
    print('请选择你的标记(X/O):')
    mark = input().upper()
    while not mark == 'X' and not mark == 'O':
        print('输入错误!请重新选择你的标记(X/O):')
        mark = input().upper()

    if mark == 'X':
        return ['X','O']
    else:
        return ['O','X']

def MakeMove(board,mark,xstart,ystart):
    TilesToFlip = IsValidMove(board,mark,xstart,ystart)

    if TilesToFlip == False:
        return False

    board[xstart][ystart] = mark
    for x,y in TilesToFlip:
        board[x][y] = mark
    return True

def GetBoardCopy(board):
    BoardCopy = GetNewBoard()

    for x in range(WIDTH):
        for y in range(HEIGHT):
            BoardCopy[x][y] = board[x][y]

    return BoardCopy

def IsOnCorner(x,y):
    return (x == 0 or x == WIDTH-1) and (y == 0 or y == HEIGHT-1)

def GetPlayerMove(board,PlayerMark):
    DIGITS_SIZE = '1 2 3 4 5 6 7 8'.split()

    while True:
        print('请输入你的行动(一个两位数,十位和个位分别代表纵坐标和横坐标;输入“退出”可以结束游戏,输入“提示”可以打开/关闭提示,提示将会以“.“的形式显示。建议不要开启提示,开启后可能会有Bug。)')
        move = input()
        if move == '退出' or move == '提示':
            return move

        if len(move) == 2 and move[0] in DIGITS_SIZE and move[1] in DIGITS_SIZE:
            x = int(move[0]) - 1
            y = int(move[1]) - 1
            if IsValidMove(board, PlayerMark, x, y) == False:
                print("你输入的位置上已经有棋子了,或者该位置不能翻转任何棋子。")
                continue
            else:
                break
        else:
            print('这不符合输入规则,请按规则输入。')

    return [x,y]

def GetScoreOfBoard(board):
    xscore = 0
    oscore = 0
    for x in range(WIDTH):
        for y in range(HEIGHT):
            if board[x][y] == 'X':
                xscore += 1
            if board[x][y] == 'O':
                oscore += 1
    return {'X':xscore, 'O':oscore}

def GetComputerMove(board,ComputerMark):
    PossibleMoves = GetValidMoves(board,ComputerMark)
    random.shuffle(PossibleMoves)

    # 如果可以在一个角上落子,那就再那里落子
    for x,y in PossibleMoves:
        if IsOnCorner(x,y):
            return [x,y]

    # 寻找分数最高的移动
    BestScore = -1
    for x,y in PossibleMoves:
        BoardCopy = GetBoardCopy(board)
        MakeMove(BoardCopy,ComputerMark,x,y)
        score = GetScoreOfBoard(BoardCopy)[ComputerMark]
        if score > BestScore:
            BestMove = [x,y]
            BestScore = score
    return BestMove

def PrintScore(board,PlayerMark,ComputerMark):
    scores = GetScoreOfBoard(board)
    print('''当前对局情况:
    你:{}个棋子   电脑:{}个棋子'''.format(scores[PlayerMark],scores[ComputerMark]))

def PlayGame(PlayerMark,ComputerMark):
    ShowHints = False
    first = True
    if PlayerMark == 'X':
        turn = '玩家'
    else:
        turn = '电脑'
    print(turn + "先走。")
    print()

    board = GetNewBoard()
    board[3][3] = 'X'
    board[3][4] = 'O'
    board[4][3] = 'O'
    board[4][4] = 'X'

    while True:
        PlayerValidMoves = GetValidMoves(board,PlayerMark)
        ComputerValidMoves = GetValidMoves(board,ComputerMark)

        if PlayerValidMoves == [] and ComputerValidMoves == []:
            return board # 谁也动不了,结束游戏
        elif turn == '玩家':
            if PlayerValidMoves != []:
                if ShowHints:
                    if not first:
                        print('========================================================================')
                    ValidMovesBoard = GetBoardWithValidMoves(board, PlayerMark)
                    DrawBoard(ValidMovesBoard)
                else:
                    if not first:
                        print('========================================================================')
                    DrawBoard(board)
                PrintScore(board, PlayerMark, ComputerMark)

                move = GetPlayerMove(board,PlayerMark)
                if move == '退出':
                    print("感谢您的游玩!")
                    sys.exit()
                elif move == '提示':
                    ShowHints = not ShowHints
                    continue
                else:
                    MakeMove(board,PlayerMark,move[0],move[1])
            else:
                print("你暂时不可以移动哦!")
            turn = '电脑'
        elif turn == '电脑':
            if ComputerValidMoves != []:
                if not first:
                    print('------------------------------------------------------------------------')
                DrawBoard(board)
                PrintScore(board,PlayerMark,ComputerMark)

                input('电脑已经放置了棋子,按下回车键以查看棋盘,并完成您的下一步。')
                move = GetComputerMove(board,ComputerMark)
                MakeMove(board,ComputerMark,move[0],move[1])
            turn = '玩家'
        first = False


def main():
    print("欢迎来到黑白翻转棋游戏!")
    print("需要了解游戏规则吗?(yes/no)")
    if input().lower().startswith('y'):
        PrintRules()
    PlayerMark,ComputerMark = GetPlayerMark()

    while True:
        FinalBoard = PlayGame(PlayerMark,ComputerMark)

        DrawBoard(FinalBoard)
        scores = GetScoreOfBoard(FinalBoard)
        print('''棋子情况:
        棋子X:{}个    棋子O:{}个'''.format(scores['X'],scores['O']))
        if scores[PlayerMark] > scores[ComputerMark]:
            print("你战胜了电脑!你比电脑多了{}个棋子!佩服!".format(scores[PlayerMark] - scores[ComputerMark]))
        elif scores[PlayerMark] < scores[ComputerMark]:
            print("你输了。你比电脑少了{}个棋子。再加把劲吧!".format(scores[ComputerMark] - scores[PlayerMark]))
        else:
            print("你和电脑实力相当!")

        print("你想再玩一局吗?(yes/no)")
        if not input().lower().startswith('y'):
            break

if __name__ == '__main__':
    main()

 

【提示】

部分含有Python第三方库相关内容的作品,在海龟编辑器网页端无法运行哦!如遇到这种情况,可以打开下面的链接,下载海龟编辑器客户端:

https://python.codemao.cn


回复

上一页1 页 / 共 0下一页