用python实现小时候的石子游戏

# 俩子抵一个
# 游戏规则
# 1 黑白双方各四枚棋,棋盘 4X4
# 2 黑棋先
# 3 横向或竖向 三枚棋子连续 黑棋2枚白棋一枚则该枚白棋出局,反之亦然。
# 4 一方剩余棋子小于2枚,则另一方胜

import pprintpp

class Chess(object):

    def __init__(self, uid, flag, location=None):
        self.uid = uid
        self.flag = flag
        self.location = location

    def __str__(self):
        return self.flag

class Board(object):
    dir = {‘u‘: (-1, 0), ‘r‘: (0, 1), ‘d‘: (1, 0), ‘l‘: (0, -1)}
    error = ‘ERROR‘

    def __init__(self, flag1, flag2):
        self.layout = [[0, 0, 0, 0],
                       [0, 0, 0, 0],
                       [0, 0, 0, 0],
                       [0, 0, 0, 0]]
        self.flag1 = flag1
        self.flag2 = flag2
        str1 = self.flag1+self.flag1+self.flag2
        str2 = self.flag2+self.flag2+self.flag1
        self.label =[str1, str2]
        self.chesses = {flag1: [], flag2: []}
        for x in range(4):
            self.layout[0][x] = self.flag1+str(x+1)
            self.layout[3][x] = self.flag2+str(x+1)
            a = Chess(x, self.flag1+str(x+1), (0, x))
            self.chesses[flag1].append(a)
            b = Chess(x, self.flag2+str(x+1), (3, x))
            self.chesses[flag2].append(b)

    def __rule(self):
        lay = self.layout
        label = self.label
        result = None
        for x in range(4):
            for y in range(4):
                a = lay[x][y]
                if a == 0:
                    continue
                else:
                    a = a[0]
                if x < 2:
                    b = lay[x - 3][y]
                    b = b[0] if b != 0 else b
                    c = lay[x - 2][y]
                    c = c[0] if c != 0 else c
                    abc = str(a) + str(b) + str(c)
                    if abc in label or abc[::-1] in label:
                        if a == b:
                            lay[x - 2][y] = 0
                            result = x+2, y
                            break
                        else:
                            lay[x][y] = 0
                            result = x, y
                            break
                if y < 2:
                    b = lay[x][y - 3]
                    b = b[0] if b != 0 else b
                    c = lay[x][y - 2]
                    c = c[0] if c != 0 else c
                    abc = str(a) + str(b) + str(c)
                    if abc in label or abc[::-1] in label:
                        if a == b:
                            lay[x][y - 2] = 0
                            result = x, y + 2
                            break
                        else:
                            lay[x][y] = 0
                            result = x, y
                            break

        return result

    def __update(self):
        a = self.__rule()
        info =‘‘
        if a:
            ch1 = len(self.chesses[self.flag1])
            self.chesses[self.flag1] = [ch for ch in self.chesses[self.flag1] if ch.location != a]
            self.chesses[self.flag2] = [ch for ch in self.chesses[self.flag2] if ch.location != a]
            if len(self.chesses[self.flag1]) < ch1:
                info = ‘【‘+self.flag1+‘】失去一枚棋子‘
            else:
                info = ‘【‘ + self.flag2 + ‘】失去一枚棋子‘

        return info

    def chess_move(self, flag, num, d):
        chess = [x for x in self.chesses[flag] if x.uid == (num-1)][0]
        a, b = chess.location
        x = a + Board.dir[d][0]
        y = b + Board.dir[d][1]
        info =‘‘
        if x < 0 or x > 3 or y < 0 or y > 3 or self.layout[x][y] != 0:
            return Board.error
        else:
            self.layout[a][b] = 0
            chess.location = x, y
            self.layout[x][y] = chess.flag
            print(‘【‘+flag+‘】移动了棋子{}-->{}‘.format((a, b), (x, y)))
            rst = self.__update()
            print(rst)
            print(self.layout)
            if len(self.chesses[self.flag1]) < 2:
                info = ‘【‘+self.flag2+‘】获胜,GAME OVER‘
            if len(self.chesses[self.flag2]) < 2:
                info = ‘【‘ + self.flag1 + ‘】获胜,GAME OVER ‘

            return info

class Gamer(object):

    def __init__(self, flag):
        self.flag = flag

    def move_chess(self, num, d, bd):
        return bd.chess_move(self.flag, num, d)

if __name__ == ‘__main__‘:
    person1 = Gamer(‘b‘)
    person2 = Gamer(‘w‘)
    board = Board(person1.flag, person2.flag)
    while True:
        print(board.layout)
        tmp = ‘【{}】拥有棋子:{};【{}】拥有棋子:{}‘
        info1, info2 = ‘‘, ‘‘
        for x in board.chesses[person1.flag]:
            info1 += x.flag+‘ ‘
        for x in board.chesses[person2.flag]:
            info2 += x.flag+‘ ‘
        print(tmp.format(person1.flag, info1, person2.flag, info2))
        print(‘【‘ + person1.flag + ‘】请选择棋子,输入棋子数字‘)
        c = int(input())
        print(‘请选择移动方向 u:上,r:右 d:下 l:左‘)
        direction = input()
        result = person1.move_chess(c, direction, board)
        if "GAME OVER" in result:
            print(result)
            break
        elif result == "ERROR":
            print("重新开始")
            continue
        else:
            print(result)
        print(‘【‘ + person2.flag + ‘】请选择棋子,输入棋子数字‘)
        c = int(input())
        print(‘请选择移动方向 u:上,r:右 d:下 l:左‘)
        direction = input()
        result = person2.move_chess(c, direction, board)
        if "GAME OVER" in result:
            print(result)
            break
        elif result == "ERROR":
            print("重新开始")
            continue
        else:
            print(result)

  自己写的小游戏,原创原创原创

玩家类 Gamer , 棋子类 Chess,棋盘类 Board,

时间: 2024-11-06 21:57:39

用python实现小时候的石子游戏的相关文章

poj 1067||hdu 1527 取石子游戏(博弈论,Wythoff Game)

取石子游戏 Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 37893   Accepted: 12684 Description 有两堆石子,数量任意,可以不同.游戏开始由两个人轮流取石子.游戏规定,每次有两种不同的取法,一是可以在任意的一堆中取走任意多的石子:二是可以在两堆中同时取走相同数量的石子.最后把石子全部取完者为胜者.现在给出初始的两堆石子的数目,如果轮到你先取,假设双方都采取最好的策略,问最后你是胜者还是败者

HDU 1527 取石子游戏 威佐夫博弈

题目来源:HDU 1527 取石子游戏 题意:中文 思路:威佐夫博弈 必败态为 (a,b ) ai + i = bi     ai = i*(1+sqrt(5.0)+1)/2   这题就求出i然后带人i和i+1判断是否成立 以下转自网上某总结 有公式ak =[k(1+√5)/2],bk= ak + k  (k=0,1,2,-,n 方括号表示取整函数) 其中出现了黄金分割数(1+√5)/2 = 1.618-,因此,由ak,bk组成的矩形近似为黄金矩形 由于2/(1+√5)=(√5-1)/2,可以先

HDU 2176 取(m堆)石子游戏 博弈

取(m堆)石子游戏 Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 3598    Accepted Submission(s): 2151 Problem Description m堆石子,两人轮流取.只能在1堆中取.取完者胜.先取者负输出No.先取者胜输出Yes,然后输出怎样取子.例如5堆 5,7,8,9,10先取者胜,先取者第1次取

BZOJ 1874: [BeiJing2009 WinterCamp]取石子游戏 [Nim游戏 SG函数]

小H和小Z正在玩一个取石子游戏. 取石子游戏的规则是这样的,每个人每次可以从一堆石子中取出若干个石子,每次取石子的个数有限制,谁不能取石子时就会输掉游戏. 小H先进行操作,他想问你他是否有必胜策略,如果有,第一步如何取石子. N≤10 Ai≤1000 裸SG函数啊 然而我连SG函数都不会求了,WA了一会儿之后照别人代码改发现vis公用了... #include <iostream> #include <cstdio> #include <cstring> #includ

BZOJ 1115: [POI2009]石子游戏Kam

1115: [POI2009]石子游戏Kam Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 924  Solved: 574[Submit][Status][Discuss] Description 有N堆石子,除了第一堆外,每堆石子个数都不少于前一堆的石子个数.两人轮流操作每次操作可以从一堆石子中移走任意多石子,但是要保证操作后仍然满足初始时的条件谁没有石子可移时输掉游戏.问先手是否必胜. Input 第一行u表示数据组数.对于每组数据,第一行

poj1067-取石子游戏 (威佐夫博弈) 【博弈】

http://poj.org/problem?id=1067 取石子游戏 Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 36753   Accepted: 12446 Description 有两堆石子,数量任意,可以不同.游戏开始由两个人轮流取石子.游戏规定,每次有两种不同的取法,一是可以在任意的一堆中取走任意多的石子:二是可以在两堆中同时取走相同数量的石子.最后把石子全部取完者为胜者.现在给出初始的两堆石子的数目,如

hdu 2516 取石子游戏

取石子游戏 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 2816    Accepted Submission(s): 1626 Problem Description 1堆石子有n个,两人轮流取.先取者第1次可以取任意多个,但不能全部取完.以后每次取的石子数不能超过上次取子数的2倍.取完者胜.先取者负输出"Second win&qu

BZOJ 1413 取石子游戏(DP)

题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=1413 题意:n堆石子排成一排.每次只能在两侧的两堆中选择一堆拿.至少拿一个.谁不能操作谁输. 思路:参考这里. int f1[N][N],f2[N][N],n,a[N]; void deal() { RD(n); int i,j,k; FOR1(i,n) RD(a[i]),f1[i][i]=f2[i][i]=a[i]; int p,q,x; for(k=2;k<=n;k++) for(

POJ - 1067 取石子游戏(包括贝蒂定理的巧妙证明)

关键词: 取石子游戏.威佐夫博奕.betty贝蒂定理.胜态.负态.状态转移.覆盖(分划).高斯函数.第二数学归纳法.黄金分割比例 题目: Description 有两堆石子,数量任意,可以不同.游戏开始由两个人轮流取石子.游戏规定,每次有两种不同的取法,一是可以在任意的一堆中取走任意多的石子:二是可以在两堆中同时取走相同数量的石子.最后把石子全部取完者为胜者.现在给出初始的两堆石子的数目,如果轮到你先取,假设双方都采取最好的策略,问最后你是胜者还是败者. Input 输入包含若干行,表示若干种石