我认为这是使用马尔可夫链的好方法。看看here
基本思想是,对于每个当前状态,都有可能进入下一个状态。您可以创建当前状态是什么的概率矩阵,以及下一个状态可能是什么的概率。然后使用这些权重从random.choices 中拉出。你可以让它变得像你想要的那样复杂。关键是从简单开始,让它发挥作用,然后你可以添加更多并修饰它(例如,我要添加 3 分未命中和 3 分取得的状态,(你还必须包括丢 2 分、投 2 分的概率……或者你可以把它作为投篮投丢和投篮命中的延伸),但我想我会把它留给你处理并在那里添加。你也可以添加在进攻和防守犯规中,如果是防守投篮犯规,投篮是否有助攻的概率等)
这只是设置一些功能来跟踪一切并“发挥”控球权的问题。
这是我的例子:
1.为每个团队创建概率矩阵。索引将是当前状态,列是下一个状态。
注意:您希望每行的总和为 1
import pandas as pd
import random
prob_matrix_A = pd.DataFrame([
[0, 0.05, 0.1, 0.375, 0.475, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 1],
[0, 0, 0, 0, 0, 0, 0, 1],
[0, 0.02, 0, 0, 0, 0.19, 0.79, 0],
[0, 0, 0, 0, 0, 0, 0, 1],
[1, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 1],
[0, 0, 0, 0, 0, 0, 0, 0]],
columns = ['Possession', 'Unforced Turnover','Steal','Miss Shot','Made Shot','Off Reb','Def Rebound', 'Change Possession'],
index = ['Possession', 'Unforced Turnover','Steal','Miss Shot','Made Shot','Off Reb','Def Rebound', 'Change Possession'])
prob_matrix_B = pd.DataFrame([
[0, 0.05, 0.1, 0.475, 0.375, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 1],
[0, 0, 0, 0, 0, 0, 0, 1],
[0, 0.02, 0, 0, 0, 0.09, 0.89, 0],
[0, 0, 0, 0, 0, 0, 0, 1],
[1, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 1],
[0, 0, 0, 0, 0, 0, 0, 0]],
columns = ['Possession', 'Unforced Turnover','Steal','Miss Shot','Made Shot','Off Reb','Def Rebound', 'Change Possession'],
index = ['Possession', 'Unforced Turnover','Steal','Miss Shot','Made Shot','Off Reb','Def Rebound', 'Change Possession'])
这是 A 队的概率矩阵:
print (prob_matrix_A.to_string())
Possession Unforced Turnover Steal Miss Shot Made Shot Off Reb Def Rebound Change Possession
Possession 0 0.05 0.1 0.375 0.475 0.00 0.00 0
Unforced Turnover 0 0.00 0.0 0.000 0.000 0.00 0.00 1
Steal 0 0.00 0.0 0.000 0.000 0.00 0.00 1
Miss Shot 0 0.02 0.0 0.000 0.000 0.19 0.79 0
Made Shot 0 0.00 0.0 0.000 0.000 0.00 0.00 1
Off Reb 1 0.00 0.0 0.000 0.000 0.00 0.00 0
Def Rebound 0 0.00 0.0 0.000 0.000 0.00 0.00 1
Change Possession 0 0.00 0.0 0.000 0.000 0.00 0.00 0
2。设置如何记录比分以及哪支球队拥有球权:
team_score_limit = 25
# game setup
game_dict = {'team_a':{'score':0, 'possession':False, 'prob_matrix': prob_matrix_A},
'team_b':{'score':0, 'possession':False, 'prob_matrix': prob_matrix_B},
'score_limit':team_score_limit}
# Do a jump ball to see who starts with ball
# Lets say team_a has 55% of getting the jump, and team_b 45%
wins_jump = random.choices(['team_a','team_b'], weights=[.55,.45], k=1)[0]
game_dict[wins_jump]['possession'] = True
print('%s: Wins the jump ball' %wins_jump)
3.创建函数来确定谁拥有球权(即谁在进攻、谁在防守):
# Function to return who has possession
def possession(game_dict):
for k, v in game_dict.items():
if type(v) == dict:
if v['possession'] == True:
offense_team = k
if v['possession'] == False:
defense_team = k
return offense_team, defense_team
4.创建函数以根据概率进行控球:
def play(current_state, game_dict):
# Determine who has possession and get their prob matrix
offense, defense = possession(game_dict)
prob_matrix = game_dict[offense]['prob_matrix']
states_list = prob_matrix.columns.tolist()
weights = prob_matrix.loc[current_state,:].tolist()
# Based on current state weights, get the next state
new_state = random.choices(states_list, weights=weights, k=1)[0]
if 'Possession' not in new_state:
if new_state in ['Def Rebound', 'Steal']:
print ('%s: %s by %s' %(offense, new_state, defense))
else:
print ('%s: %s' %(offense, new_state))
current_state = new_state
if current_state == 'Made Shot':
game_dict[offense]['score'] += 2
# if team_a score reached the limit, we'll return False to stop the game
if game_dict['team_a']['score'] >= game_dict['score_limit']:
return False
# if it's a change of possession, we'll update our game_dict
if new_state == 'Change Possession':
game_dict[offense]['possession'] = False
game_dict[defense]['possession'] = True
# else the team who currently possess the ball didn't change from the previous outcome (Ie. Offensive rebound), then they get another possession play
else:
play(current_state, game_dict)
5.设置初始current_state 开始“游戏”并进行游戏:
# Play the first quarter
current_state = 'Possession'
continue_play = True
while continue_play != False:
continue_play = play(current_state, game_dict)
print ('\nEnd of 1st Quarter!\n')
print ('**************************')
print ('team_a: %s\tteam_b: %s' %(game_dict['team_a']['score'],game_dict['team_b']['score']))
输出:
runfile('test.py', wdir='C:/test')
team_a: Wins the jump ball
team_a: Made Shot
team_b: Miss Shot
team_b: Off Reb
team_b: Made Shot
team_a: Made Shot
team_b: Made Shot
team_a: Miss Shot
team_a: Def Rebound by team_b
team_b: Miss Shot
team_b: Def Rebound by team_a
team_a: Steal by team_b
team_b: Miss Shot
team_b: Def Rebound by team_a
team_a: Miss Shot
team_a: Def Rebound by team_b
team_b: Made Shot
team_a: Miss Shot
team_a: Def Rebound by team_b
team_b: Steal by team_a
team_a: Made Shot
team_b: Made Shot
team_a: Made Shot
team_b: Made Shot
team_a: Made Shot
team_b: Steal by team_a
team_a: Made Shot
team_b: Miss Shot
team_b: Def Rebound by team_a
team_a: Unforced Turnover
team_b: Made Shot
team_a: Steal by team_b
team_b: Made Shot
team_a: Unforced Turnover
team_b: Steal by team_a
team_a: Made Shot
team_b: Unforced Turnover
team_a: Miss Shot
team_a: Off Reb
team_a: Made Shot
team_b: Miss Shot
team_b: Def Rebound by team_a
team_a: Made Shot
team_b: Miss Shot
team_b: Def Rebound by team_a
team_a: Made Shot
team_b: Made Shot
team_a: Made Shot
team_b: Miss Shot
team_b: Def Rebound by team_a
team_a: Miss Shot
team_a: Off Reb
team_a: Made Shot
team_b: Miss Shot
team_b: Def Rebound by team_a
team_a: Made Shot
End of 1st Quarter!
**************************
team_a: 26 team_b: 16