按每季比赛数生成NBA比赛

2024-09-28 19:31:03 发布

您现在位置:Python中文网/ 问答频道 /正文

我正试图通过每季的比赛来创造NBA比赛

我是如何做到这一点的,我选择了一支球队在四分之一的时间内可以得分的数量,然后生成满足这些数量的分数的比赛

假设我选择A队在四分之一的时间里拿下5分。我做了一个算法来生成这个示例列表:

[['2分','SWITCH'],['MISSED 2分','进攻篮板','停留',['3分','SWITCH']]

(这个列表比实际生成的要简单得多。除了抢断和失误之外,我添加了更多的功能,比如助攻和篮板。)

“切换”表示切换所有物,而“停留”表示当前团队保留所有物。每个“切换”需要在其他团队的列表中至少有一个操作可用,而每个“停留”需要在当前团队的列表中至少有一个操作可用

现在,当我为两个不同的团队创建两个列表时,他们的列表可能长度不同,因为(除其他外)一个团队可能得分高于另一个团队

当我试图将这两个列表合并在一起创建逐场模拟时,这可能会导致一个团队在另一个团队上有“切换”时没有动作

我的问题是如何在任何团队列表中添加额外的“切换”或“停留”,以便每个“切换”都在其他团队的列表中有一个操作,而每个“停留”都在当前团队的列表中有一个操作

我的第一个想法是在列表中添加随机失误和偷盗(导致“切换”)并希望它能起作用,但我想不出一个方法来实现这一点

此外,只要列表满足所需的得分数,初始团队列表的顺序就无关紧要

这就是我到目前为止所做的:

def join_steals_tov(团队列表、团队列表):

overall_list = []

possession = 'Team A'

print(len(teamA_list))
print(len(teamB_list))

while teamA_list and teamB_list:
    
    if possession == 'Team A':
        play = teamA_list.pop(0)
        play.insert(0,'Team A')
        overall_list.append(play)
        print(f"Team A: {play}")
        
        if play[-1] == 'SWITCH':
            possession = 'Team B'
    else:
        play = teamB_list.pop(0)
        play.insert(0,'Team B')
        overall_list.append(play)
        print(f"Team B: {play}")
        
        if play[-1] == 'SWITCH':
            possession = 'Team A'
    
return teamA_list, teamB_list, overall_list

Tags: 列表play数量if时间团队分数team
2条回答

我认为这是处理马尔可夫链的一个好方法。看一看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

这里有一种可能的方法来生成一个季度的逐场比赛列表,从两个得分事件列表开始,例如

teamA_scores = ['A2', 'A3']          
teamB_scores = ['B3', 'B3', 'B2']

步骤1:将列表合并为单个列表,并将合并后的列表洗牌,例如

scores: ['A3', 'B3', 'A2', 'B3', 'B2']
          ^^  - team A scores 3 points

第二步:当同一队连续得分两次时,必须有另一队未得分的事件。因此,创建一个新的播放列表,其中包括那些必须切换的播放,例如

switch: ['A3', 'B3', 'A2', 'B3', 'AS', 'B2']
                                  ^^  - team A gives the ball back to team B without scoring

步骤3:在列表中添加一个季度末比赛(只是为了让下一步更容易),例如

end Q:  ['A3', 'B3', 'A2', 'B3', 'AS', 'B2', 'AQ']
                                              ^^  - time runs out with team A in possession

第4步:现在添加一些额外的非得分游戏来填充这个季度。在示例代码中,播放列表被填充为10的任意长度。为了真实感,您需要为每个剧本指定一个时间,并填充列表,直到总时间为12分钟

plays:  ['AK', 'A3', 'B3', 'AS', 'BS', 'A2', 'B3', 'AS', 'B2', 'AQ']
          ^^  - team A keeps the ball, e.g. missed shot, offensive rebound
                            ^^  - team A loses the ball
                                  ^^  - team B loses the ball

下面是一些示例代码,展示了如何从两个得分重头戏列表中创建10个重头戏的列表:

from random import shuffle
from random import randrange
from random import randint

# helper functions
def getTeam(event):
    return event[0]

def makeSameTeamItem(event, item):
    if getTeam(event) == 'A':
        return 'A' + item
    else:
        return 'B' + item

def makeOtherTeamItem(event, item):
    if getTeam(event) == 'B':
        return 'A' + item
    else:
        return 'B' + item

# start with a list of scores for each team
teamA_scores = ['A2', 'A3']
teamB_scores = ['B3', 'B3', 'B2']

# step 1: combine and shuffle to create an overall list of scores
scores = teamA_scores + teamB_scores
shuffle(scores)
print 'scores:', scores

# step 2: create list of plays including mandatory SWITCH plays
plays = []
plays.append(scores[0])
for i in range(1, len(scores)):
   if getTeam(scores[i]) == getTeam(scores[i-1]):
      plays.append(makeOtherTeamItem(scores[i], 'S'))
   plays.append(scores[i])
print 'switch:', plays

# step 3: add the end of quarter play
plays.append(makeOtherTeamItem(scores[-1], 'Q'))
print 'end Q: ', plays

# step 4: insert additional non-scoring plays to fill the quarter
quarter = 10
while len(plays) < quarter:
   index = randrange(0, len(plays))
   if quarter - len(plays) == 1 or randint(1,2) == 1:
      plays.insert(index, makeSameTeamItem(plays[index], 'K'))
   else:
      plays.insert(index, makeOtherTeamItem(plays[index], 'S'))
      plays.insert(index, makeOtherTeamItem(plays[index], 'S'))
print 'plays: ', plays

相关问题 更多 >