时荒小先生 发表于 2020-3-16 14:04:08

井字棋?安排!!

本帖最后由 一个账号 于 2020-3-16 14:26 编辑

python小白来展示学习成果啦!!!! 希望各位帅气的小哥哥漂亮的小姐姐们能指点一下下{:9_221:}

最近在看一本python入门书《python游戏编程快速上手》感觉这本书还是不错滴,很适合像我这个亚子的白白的小白

书里面有一个TicTacToe也就是井字棋游戏,看着书编了一遍又自己实现了一下下,好了废话不多说,先上波儿效果图(让我找找哈,不知道存哪了{:10_266:} )




第一次展示作品,不知道该说点啥。。。。

效果呢就上上面这两张图展示的那个亚子,是不是有点小失望呀,这TM是啥破游戏,连个正儿八经的界面都没。

emmmmmm刚开始学Python嘛,嘿嘿,等我以后学成归来,一定要把我的井字棋改成不同寻常的、高端大气上档次的....井字棋

下面我来稍微说一下这个小游戏吧,顺便复习一下。

有兴趣的童鞋们可以自己实现一下子呀,如果大家有啥想法或者发现我有哪里写的不好,欢迎评论交流呦{:10_327:}



这个是书上给出的流程图,emmmm,是不是有点乱呀?! 不用怕,我自己又做了一张流程图(是不是莫名又开始恐慌了???hhhhh)



没错,就是咱们的编辑神器IDLE,hhhhh,大概思路就是这样梓吧,然后就是按照写好的思路来编写程序了

首先呢,咱们稍微看下写好的流程,对于重复出现的操作可考虑一下函数之类的东东,比如咱们看到好多地方要展示游戏板,那就把这一块函数封装到一个函数里呗

就像这样

def draw_board(board, nums=[' ']*10):
    """展示游戏板"""
    # board 是一个含有十个元素的列表,第一个元素不用管,只是抵消差一行为
    print("    |    |")
    print(" " + board + "| " + board + "| " + board)
    print(nums, "|", nums, " |", nums)
    print("----------------")
    print("    |    |")
    print(" " + board + "| " + board + "| " + board)
    print(nums, "|", nums, " |", nums)
    print("----------------")
    print("    |    |")
    print(" " + board + "| " + board + "| " + board)
    print(nums, "|", nums, " |", nums )
说实话,这个游戏板是真的简陋。。。。

然后就像这样依次定义出别的、各种各样的函数,这里就不一一赘述了。

再然后呢,就是游戏的主要股骨架了,其实我感觉可以先写游戏骨架,最后再进行重构,把差不多的代码整到一块,这样是不是更好呢?

# 开始,骚话问候
print("呕吼~~~~决一死战吧,大帅哥!!!!")

# 显示原始游戏板
draw_board([' ']*10, range(0, 10))
print("这个是游戏板,有点简陋哈,不过也要按编号落子呦!!!!")


# 进入游戏主循环
while True:
    # 重置游戏板
    the_board = [' '] * 10
    player_letter, computer_letter = choose_chess() # 让玩家选自棋子类型(x 或 o)
    turn = first_go() # 随机决定谁先走
    if turn == 'computer':
      print("本电脑小哥哥先走,你一边呆着去。。。")
    else:
      print("你先走吧")
    playing = True   # 设定标志,保证游戏正常进行和中断

    # 进入一局游戏的循环
    while playing:
      if turn == 'player':
            # 轮到玩家
            move = get_player_move(the_board)
            make_move(the_board, move, player_letter) # 让玩家落子

            # 显示游戏板
            draw_board(the_board)
            
            if is_winner(the_board, player_letter):
                # 判断是否获胜
                print("卧槽,你竟然赢了T_T\n我不服,敢不敢再来一局!?")
                playing = False
               
            elif is_full_board(the_board):
                # 判断是否平局(游戏板全装满,胜负未分)
                print("你的实力也就只配跟我打个平局吧,哼!¬︿̫̿¬")
                playing = False
               
            else:
                # 轮到电脑
                turn = 'computer'
      else:
            # 轮到电脑
            # 算法计算最佳落子位置
            move = get_computer_move(the_board, computer_letter)   
            make_move(the_board, move, computer_letter) # 让电脑落子

            # 显示游戏板
            draw_board(the_board)
            
            if is_winner(the_board, computer_letter):
                # 判断是否获胜
                print("呕吼,你怎么输了呢,大帅哥!!!\n啊哈哈哈哈哈~~~///(^v^)\\\~~~")
                playing = False
               
            elif is_full_board(the_board):
                # 判断是否平局
                print("你的实力也就只配跟我打个平局吧,哼!¬︿̫̿¬")
                playing = False
               
            else:
                # 轮到玩家
                turn = 'player'

    # 玩家是否要再玩一次,注意这里的缩进
    if not play_again():
      break

# 游戏结束,表达依依不舍之情
print("大帅哥,记着常来找我玩啊!!!(>人<)")


差不多就是这亚子了。

我把剩下的代码也放的这里吧,如果哪里做的还是不是很好,请在评论区留下宁宝贵的建议(此处身体弯成90度)

def choose_chess():
    """让玩家选择棋子类型"""
    print("\n请选择宁心仪的棋子类型(x 或 y) (反正选啥都得输,(¬︿̫̿¬☆))")
    letter = input().upper()
    # 防止玩家选别的字母
    while not (letter == 'X' or letter == 'Y'):
      print("骚凹瑞!宁只能在 X 和 Y 中选择一个呦!!!!")
      letter = input().upper()
   
    # 返回一个列表,第一个元素为玩家的棋子,第二个为电脑的棋子
    if letter == 'X':
      return ['X', 'Y']
    else:
      return ['Y', 'X']


def first_go():
    """随机决定谁先走"""
    if random.randint(0, 1) == 0:
      return 'player'
    else:
      return 'computer'


def is_free(board, move):
    """判断某位置是否为空, 如果为空就返回True"""
    copy = board[:] # 注意这里使用列表复制,防止更改原列表
    return copy == ' '

   
def get_player_move(board):
    """获得玩家的落子位置"""
    print("\n大帅哥,到你了。请输入:(1 - 9)")
    print("快点!我还想早点把你打得落花流水呢!!!")
    move = input()

    # 确保玩家的输入合法
    while not ((move in ) or is_free(board, int(move))):
      print("你咋不按规矩出牌呢。。。")
      print("请重新输入吧!")
      move = input()
    return int(move)


def make_move(board, move, letter):
    """根据所给位置落子"""
    board = letter # 注意这里能修改局部变量board 的原因, 列表引用


def is_winner(bo, le):
    """判断玩家或电脑是否获胜"""
    # 用 bo 代替 board、le 代替 letter,比较方便
    return ((bo == le and bo == le and bo == le) or # 判断最上面一行是否一致
            (bo == le and bo == le and bo == le) or # 判断中间一行
            (bo == le and bo == le and bo == le) or # 判断最下面一行
            (bo == le and bo == le and bo == le) or # 判断最左边一列
            (bo == le and bo == le and bo == le) or # 判断中间一列
            (bo == le and bo == le and bo == le) or # 判断最右边一列
            (bo == le and bo == le and bo == le) or # 判断主对角线
            (bo == le and bo == le and bo == le)) # 判断副对角线


def is_full_board(board):
    """判断游戏板是否全装满,即是否平局"""
    copy = board[:]
    is_full = True
   
    for i in range(1, 10):
      if copy == ' ':
            is_full = False
    return is_full


def get_computer_move(board, computer_letter):
    """计算最佳落子位置"""
    print("\n到我了,你离死亡不远了,啊哈哈哈哈(发出小月般的笑声)")
    if computer_letter == 'X':
      player_letter = 'Y'
    else:
      player_letter = 'X'

    # 通过模拟,判断是否有能让电脑获胜的位置
    for i in range(1, 10):
      copy = board[:]
      if is_free(copy, i):
            make_move(copy, i, computer_letter)
            if is_winner(copy, computer_letter):
                return i

    # 通过模拟,判断是否有能阻止玩家获胜的位置
    for i in range(1, 10):
      copy = board[:]
      if is_free(copy, i):
            make_move(copy, i, player_letter)
            if is_winner(copy, player_letter):
                return i

    # 判断是否还有角角是空的
    move = []
    for i in :
      if is_free(board, i):
            move.append(i)
    if move:
      return random.choice(move)

    # 判断中心是否是空的
    if is_free(board, 5):
      return 5

    # 判断剩余位置(每条边的中间)是否为空
    move = []
    for i in :
      if is_free(board, i):
            move.append(i)
    if move:
      return random.choice(move)


def play_again():
    """询问玩家是否要再玩一次"""
    print("\n再来一局呗!!!!(❤ ω ❤)")
    print("请输入: (yes or no)")
    return input().lower().startswith('y')


咸小鱼一号:What!!!!!!小先生二号,你这代码西一块东一块的着实把我整懵了。。。。

咸小鱼二号:那我要不再整个发一遍吧

咸小鱼一号:..............

(写在最后:感谢每一位在咸小鱼成长道路上每一位帮助过咸小鱼的人{:5_102:} )

等等,再让我说一句,如果大家需要这本《python游戏编程快速上手》的话,可以在评论区留言或者私信我哦!!!

不说了,要上课了{:10_266:} ,拜拜啦

永恒的蓝色梦想 发表于 2020-3-16 14:10:41

前排支持楼主!

时荒小先生 发表于 2020-3-16 14:13:27

永恒的蓝色梦想 发表于 2020-3-16 14:10
前排支持楼主!

谢谢宁,{:5_102:}第一次写作品展示贴,还以为没人看呢(嘿嘿)

一个账号 发表于 2020-3-16 14:15:09

加个界面就更好了

时荒小先生 发表于 2020-3-16 14:18:56

一个账号 发表于 2020-3-16 14:15
加个界面就更好了

嗯嗯,我努力学学,嘿嘿

一个账号 发表于 2020-3-16 14:19:59

时荒小先生 发表于 2020-3-16 14:18
嗯嗯,我努力学学,嘿嘿

加油!!

隔壁繁星吖 发表于 2020-3-16 14:32:45

逐渐小月化,加油

时荒小先生 发表于 2020-3-16 14:40:01

隔壁繁星吖 发表于 2020-3-16 14:32
逐渐小月化,加油

嘿嘿{:5_109:}谢谢宁

407102617 发表于 2020-3-16 14:52:24

有意思

小猴猴 发表于 2020-3-16 15:13:40

博主太可爱了吧

王富帅 发表于 2020-3-16 15:52:37

有意思

liuzhengyuan 发表于 2020-3-16 18:26:13

这个是不会赢得吗?我完了好几局都没赢{:10_284:}

时荒小先生 发表于 2020-3-16 19:23:37

liuzhengyuan 发表于 2020-3-16 18:26
这个是不会赢得吗?我完了好几局都没赢

可以吧,虽然我也没赢几下{:10_266:}

一个账号 发表于 2020-3-16 19:30:17

时荒小先生 发表于 2020-3-16 19:23
可以吧,虽然我也没赢几下

游戏有 Bug,可以走自己或电脑走过的地方

时荒小先生 发表于 2020-3-16 20:20:06

一个账号 发表于 2020-3-16 19:30
游戏有 Bug,可以走自己或电脑走过的地方

啊???我都没试过走已经走过的地方,我赶紧改改{:10_266:}
谢谢宁提醒了

时荒小先生 发表于 2020-3-16 20:34:32

一个账号 发表于 2020-3-16 19:30
游戏有 Bug,可以走自己或电脑走过的地方

懂了,get_player_move函数有点问题,那个while语句可以改成这个
while (move not in ) or (not is_free(board, int(move))):
我原来那个虽然not 只有一个,可是我加括号了呀{:10_266:}
while not ((move in ) or is_free(board, int(move))):
这个有点懵,那个is_free函数是空的时候返回True

beatlemay 发表于 2020-3-16 20:52:33

楼主有电子资源吗,小弟求一手1322055350@qq.com.另外,刚刚试了一下楼主的代码,出现了棋子可重复,而且九宫格的数字对应不是很清楚

时荒小先生 发表于 2020-3-16 21:26:20

beatlemay 发表于 2020-3-16 20:52
楼主有电子资源吗,小弟求一手.另外,刚刚试了一下楼主的代码,出现了棋子可重复,而且九宫格的数字对应不 ...

链接:https://pan.baidu.com/s/1Do7VKvyjQ755AzcQVU2-ZQ
提取码:rwsv

顺带安利一个网站:偶书,上面有好多资源都可免费下载

如果对你有用的话,麻烦好评支持一下呗{:5_102:}

V流年V 发表于 2020-3-16 23:06:34

纯文字,好有耐心啊{:10_256:}

Judie 发表于 2020-3-17 08:25:46

{:10_275:}want《python游戏编程快速上手》
页: [1] 2 3
查看完整版本: 井字棋?安排!!