利用python处理一些小问题,主要学习此过程中语言如何应用,与c/cpp不同的地方。
列表与元组
给定一个联系人列表,每个联系人用一个元组 表示,其中有联系人的姓名name 和年龄age。
编写该程序,输入一个字符串,在联系人列表中搜索该人名,并以示例格式输出该联系人的年龄。
没找到联系人输出Not Found
python
contacts = [
('James', 42),
('Amy', 24),
('John', 31),
('Amanda', 63),
('Bob', 18)
]
name = input()
notfound = True
for x in contacts:
if(x[0] == name):
print(f"{name} is {x[1]}")
notfound = False
if notfound:
print("Not Found")
1.元组是有序的(1,2,3),集合是无序的{1,2,3}
2.在列表中的元组,for x in contacts,是一个元组一个元组遍历,而元组x[0],x[1]分别表示元组中第几个元素(有序的)
3.输出表示:print(f"{name} is {x[1]}")
面向对象编程题目
1.石头剪刀布
python
#电脑随机生成数字
import random
class Game():
#我们通过类里面的方法获得类的属性值
def __init__(self):
self.computer_pick = self.get_computer_pick()
self.user_pick = self.get_user_pick()
self.result = self.get_result()
#电脑随机生成选项 def get_computer_pick(self):
random_num = random.randint(1,3)
options = {1:"paper",2:"scissors",3:"rock"}
return options[random_num]
#用户输入获取
def get_user_pick(self):
while True:
user_pick = input('输入石头/剪子/布:')
user_pick = user_pick.lower()
if user_pick in ("paper","scissors","rock"):
break
else:
print('error input!')
return user_pick
#判断胜负
def get_result(self):
if self.computer_pick == self.user_pick:
result = '平局'
elif self.user_pick =='paper' and self.computer_pick == 'rock':
result = '获胜'
elif self.user_pick =='rock' and self.computer_pick == 'scissors':
result = '获胜'
elif self.user_pick =='scissors' and self.computer_pick == 'paper':
result = '获胜'
else:
result = '失败'
return result
#打印情况
def print_result(self):
print(f"Computer's pick: {self.computer_pick}")
print(f'Your pick: {self.user_pick}')
print(f'You {self.result}')
# 运行
if __name__ == '__main__':
game = Game()
game.print_result()
1.我第一次写的时候(刚学完类)将方法前面的self遗漏了,导致报错,代码会找全局函数get_computer_pick(),所以类里面的方法和属性需要加self哦!
2.之所以不需要调用game.get_user_pick(),game.get_computer_pick()和game.get_result()是因为把这些方法调用写入了__init__(),创建对象的时候自动调用了,只需要给输入即可打印情况!
3.其次可以学习一下利用随机模块random和字典生成不同选项的用法
python
#电脑随机生成选项
def get_computer_pick(self):
random_num = random.randint(1,3)
options = {1:"paper",2:"scissors",3:"rock"}
return options[random_num]
-------------------------------------------------------
def get_computer_pick():
options = ('rock', 'paper', 'scissors')
return random.choice(options)
4.学习一下用户输入获取正确的方法
5.学一下用类构建这类游戏的思维(函数也能构建)
2.井字游戏
在这个项目中,我们将用Python创建一个井字形游戏。

我们将使用面向对象的编程来创建这个游戏。我们的游戏将有三个类:
- 棋盘:处理井字棋盘并处理获胜/抽签逻辑
- 玩家:处理玩家的名字和他们所使用的符号
- 游戏:处理游戏逻辑
棋盘类
Board类的对象有一个名为board的属性,它是一个包含9个项目的列表。 开始的时候,每个项目的值是一个空格。 一旦玩家开始选择位置的符号,我们将用X 或O 更新这个列表的项目。 print_board()方法会以一种视觉上的直观方式打印棋盘。
python
class Board:
def __init__(self):
#用列表建立棋盘,每个格都有序号
self.board = [' ',' ',' ',
' ',' ',' ',
' ',' ',' ']
#打印棋盘
def print_board(self):
print('\n')
print(' ' + self.board[0] + ' | ' + self.board[1] + ' | ' + self.board[2])
print('-------')
print(' ' + self.board[3] + ' | ' + self.board[4] + ' | ' + self.board[5])
print('-------')
print(' ' + self.board[6] + ' | ' + self.board[7] + ' | ' + self.board[8])
board = Board()
玩家类
添加Player类。这个类的对象有两个属性。
type: 用于符号 "X" 或 "O"。name:用于存储玩家的名字。
假设第一个球员总是采取 "X" 符号,第二个球员总是采取 "O" 符号。
**get_name()**方法用来获取球员的名字。
python
class Player:
def __init__(self,type):
self.type = type
self.name = self.get_player_name()
self.print_player()
def get_player_name(self):
if self.type == 'X':
name = input('选择X的玩家输入姓名:')
else:
name = input('选择O的玩家输入姓名:')
return name
def print_player(self):
print(f'玩家{self.name}选择{self.type}')
# 创建用于测试的玩家对象
player1 = Player('X')
player2 = Player('O')
1.注意__init__()函数中初始化顺序,self.type必须在self.get_player_name()前面,因为get_player_name()中用到了self.type,此时需要被定义才行。
2.代码专业性角度分析写法:把 self.name 的赋值封装在 get_name() 里是否更高效可行?
可行,但不高效。
python
class Player:
def __init__(self, type):
self.type = type
self.ask_name()
def ask_name(self):
if self.type == 'X':
self.name = input('选择 X 的玩家,请输入你的名字:')
else:
self.name = input('选择 O 的玩家,请输入你的名字:')
注意看此时与上面的区别。
不好在:跑单元测试时必须人肉输入,或打补丁 input() || 类永远绑定了"控制台交互"这一上下文,想以后改成 GUI、网页、API 都得改类。直接赋值给self.name可读性差,点开ask_name()才知道self.name在此赋值。
优化:在__init__()里加入name
python
class Player:
def __init__(self, type, name=None):
self.type = type
self.name = name or self.ask_name() # 外部没给就自己去问
def ask_name(self):
return input(f'选择 {self.type} 的玩家,请输入名字:')
这样既能在生产环境自动提问,也能在测试时直接 **Player('X', 'Alice')**秒建对象
游戏类
先完成简单的棋盘更新逻辑
update_board()方法
这个方法需要三个参数:
self:调用此方法的对象position:用户选择的位置(一个整数)type- 如果当前玩家是player1',它将是'X',否则它将是'O'`。
方法首先检查position 是否已经被填充。 如果它没有被填满,我们将更新棋盘并返回True。 如果该位置已经被填满,将显示一条信息,并返回 False。
python
class Board:
def __init__(self):
#用列表建立棋盘,每个格都有序号
self.board = [' ', ' ',' ',
' ',' ',' ',
' ',' ',' ']
#打印棋盘
def print_board(self):
print('\n')
print(' ' + self.board[0] + ' | ' + self.board[1] + ' | ' + self.board[2])
print('-------')
print(' ' + self.board[3] + ' | ' + self.board[4] + ' | ' + self.board[5])
print('-------')
print(' ' + self.board[6] + ' | ' + self.board[7] + ' | ' + self.board[8])
def update_board(self,position,type):
if self.board[position] == ' ':
self.board[position] = type
return True
else:
print('位置已经被选了,请选择其他位置。')
return False
然后回到play()中完成对update_board参数的更新即可:
python
class Game:
def __init__(self):
#创建对象
self.board = Board()
self.player1 = Player('X')
self.player2 = Player('O')
#刚开局是x玩家先走(current_player也是一个对象)
self.current_player = self.player1
def play(self):
while True:
message = int(input(f'{self.current_player.name},请输入位置 (1 - 9): '))
print(message)
position = message-1
flag = self.board.update_board(position,self.current_player.type)
if flag:
if self.current_player == self.player1:
self.current_player = self.player2
else:
self.current_player = self.player1
#打印棋盘
self.board.print_board()
else:
continue
play1 = Game()
play1.play()
基本逻辑就有了,接下来就是判断输赢和平局了
- 在
Board类中增加了check_winner()和check_draw()方法。
python
class Board:
def __init__(self):
#用列表建立棋盘,每个格都有序号
self.board = [' ', ' ',' ',
' ',' ',' ',
' ',' ',' ']
#打印棋盘
def print_board(self):
print('\n')
print(' ' + self.board[0] + ' | ' + self.board[1] + ' | ' + self.board[2])
print('-------')
print(' ' + self.board[3] + ' | ' + self.board[4] + ' | ' + self.board[5])
print('-------')
print(' ' + self.board[6] + ' | ' + self.board[7] + ' | ' + self.board[8])
def update_board(self,position,type):
if self.board[position] == ' ':
self.board[position] = type
return True
else:
print('位置已经被选了,请选择其他位置。')
return False
# 检查所有的直线上的符号是否相同
def check_winner(self, type):
if (self.board[0] == type and self.board[1] == type and self.board[2] == type) or \
(self.board[3] == type and self.board[4] == type and self.board[5] == type) or \
(self.board[6] == type and self.board[7] == type and self.board[8] == type) or \
(self.board[0] == type and self.board[3] == type and self.board[6] == type) or \
(self.board[1] == type and self.board[4] == type and self.board[7] == type) or \
(self.board[2] == type and self.board[5] == type and self.board[8] == type) or \
(self.board[0] == type and self.board[4] == type and self.board[8] == type) or \
(self.board[2] == type and self.board[4] == type and self.board[6] == type):
return True
else:
return False
# 所有的格子都被选择了,并且没有胜出者。返回平局!
def check_draw(self):
if ' ' not in self.board:
return True
else:
return False
check_winner()方法
这个方法检查是否有三个相同的符号(类型)出现在一排。 如果有,则拥有该符号的玩家就赢得了游戏。 在这种情况下,我们返回 "True",否则我们返回 "False"。
我们将从游戏类的play()方法中调用这个方法。 顺便说一下,类里面的if条件非常大。这就是为什么我们使用了\来在多行中使用我们的布尔表达式。
check_draw()方法
如果棋盘上的所有字段都被填满,但仍然没有赢家,那么就是平局。 为判断棋盘是否被填满,我们判断了' '是否在棋盘上。 如果棋盘列表中没有' '(棋盘的初始值),这意味着所有的棋盘位置都被填满。
稍后我们将从游戏类的play()方法中调用这个方法,判断游戏胜负并退出循环
python
class Game:
def __init__(self):
#创建对象
self.board = Board()
self.player1 = Player('X')
self.player2 = Player('O')
#刚开局是x玩家先走(current_player也是一个对象)
self.current_player = self.player1
def play(self):
while True:
message = int(input(f'{self.current_player.name},请输入位置 (1 - 9): '))
print(message)
position = message-1
flag = self.board.update_board(position,self.current_player.type)
if flag:
#更新棋盘
self.board.print_board()
#判断游戏胜负并退出循环
if self.board.check_winner(self.current_player.type):
print(self.current_player.name,'wins!')
#有玩家获胜退出游戏循环
break
#平局
elif self.board.check_draw():
print('Game is a draw!')
break
#游戏未结束,继续
else:
if self.current_player == self.player1:
self.current_player = self.player2
else:
self.current_player = self.player1
else:
continue
自此游戏结束!
我觉得这个项目需要消化一下多练几次才能复刻,不过不难看懂!
。。。