faceoffs and functioning test game

This commit is contained in:
Sakimori 2022-01-11 13:50:01 -05:00
parent 1c6a5400a5
commit a317e079d6
3 changed files with 101 additions and 14 deletions

53
game.py
View file

@ -1,6 +1,6 @@
import random, team, player, os
import random, team, player, os, math
from team import Team
from player import Player, AtkAction, DefAction
from player import Player, AtkAction, DefAction, Skater, Goalie
from skillContests import SkillContestParams, Situations
from attributes import normalDis
from hocUtils import RinkGraph
@ -21,7 +21,8 @@ class Game(object):
self.awayZones = RinkGraph(edgeFilename=DEFAULTRINKFILENAME)
self.homeZones = RinkGraph(edgeFilename=DEFAULTRINKFILENAME)
self.currentZone = None
self.faceoff = FaceoffDot.Center
self.faceoffSpot = FaceoffDot.Center
self.playStopped = True
self.lineSize = 5
if len(awayTeam.roster) != 10 or len(homeTeam.roster) != 10 or threes:
@ -30,11 +31,11 @@ class Game(object):
self.goalieHome = self.home.chooseGoalie()
self.goalieAway = self.away.chooseGoalie()
self.positionInPossession = None
self.positionInPossession = None #use SkaterPosition enum
self.teamInPossession = None
self.skatersHome = [] #LW LD C RD RW, use the SkaterPosition enum for indexing.
self.skatersAway = []
self.skatersHome = self.home.roster[:5] #LW LD C RD RW, EA; use the SkaterPosition enum for indexing. Threes uses left winger, left defenseman, center.
self.skatersAway = self.away.roster[:5]
self.penaltyBoxAway = []
self.penaltyBoxHome = []
@ -42,22 +43,35 @@ class Game(object):
self.pulledGoalieHome = False
self.period = 1
self.clock = 60*20 #clock will be given in seconds
self.clock = 60*20 #Time remaining in period, given in seconds
self.eventLog = []
def defendingTeam(self):
if teamInPossession == self.home:
if self.teamInPossession == self.home:
return self.away
else:
return self.home
def attackingTeam(self):
"""Alias for teamInPossession, to match defendingTeam()"""
return teamInPossession
return self.teamInPossession
def homeAttacking(self):
return teamInPossession == self.home
return self.teamInPossession == self.home
def skatersInPossession(self):
return self.skatersHome if self.homeAttacking() else self.skatersAway
def clockToMinutesSeconds(self):
"""Returns a string MM:SS elapsed in period."""
elapsedSeconds = 60*20 - self.clock if self.clock >= 0 else 60*20
minutes = str(int(math.modf(elapsedSeconds/60)[1]))
seconds = str(elapsedSeconds % 60)
if len(seconds) == 1:
seconds = f"0{seconds}"
return f"{minutes}:{seconds}"
def currentSituation(self):
skatersH = self.lineSize + self.pulledGoalieHome - len(self.penaltyBoxHome)
@ -83,6 +97,22 @@ class Game(object):
defRoll = normalDis(defValue, defValue/2, 0)
return atkRoll-defRoll > 0
def faceoff(self, awayPlayer:Skater, homePlayer:Skater):
"""Hold a faceoff! True indicates home win, False is away win."""
faceoffSkills = [('Dex',50),('Sti',50),('Pas', 10)]
params = SkillContestParams(faceoffSkills, faceoffSkills)
return self.skillContest(homePlayer, awayPlayer, params) if random.random() > 0.4 else random.sample([True, False], 1)[0]
def event(self):
"""Meat and potatoes. Everything that happens is a direct result of this being called."""
if self.playStopped: #need a faceoff
self.teamInPossession = self.home if self.faceoff(self.skatersAway[SkaterPosition.C.value], self.skatersHome[SkaterPosition.C.value]) else self.away
self.positionInPossession = SkaterPosition(random.sample([0, 1, 1, 3, 3, 4],1)[0]) #wingers are less likely to recieve the faceoff than defensemen
self.playStopped = False
winningPlayer = self.skatersInPossession()[SkaterPosition.C.value]
self.eventLog.append(f"{self.clockToMinutesSeconds()} - {self.teamInPossession.shortname} {str(winningPlayer)} wins faceoff.")
self.clock -= random.randint(2,5)
class FaceoffDot(Enum):
"""All orientations are given from the perspective of the defending team."""
AwayZoneLeft = -4
@ -101,4 +131,5 @@ class SkaterPosition(Enum):
LD = 1
C = 2
RD = 3
RW = 4
RW = 4
EA = 5

View file

@ -11,7 +11,7 @@ class AttributeTest(object):
self.fakeGame = game.Game(None, None)
self.params = skillContests.SkillContestParams(self.atkAction, self.defAction)
self.params = skillContests.SkillContestParams().actionCheck(self.atkAction, self.defAction)
def lowStats(self):
"""Tests attacker and defender with minimum stats."""
@ -86,4 +86,44 @@ class AttributeTest(object):
for attr, w in self.params.defStats:
print(self.defPlayer.getAttribute(attr))
print(f"Success rate: {str(round(success/total*100,2))}%")
print("-------")
print("-------")
class TestGame(object):
def __init__(self):
awayRoster = [
player.Player("Laika", 93),
player.Player("Vivi", 16),
player.Player("Jorts", 75),
player.Player("Yuki", 23),
player.Player("Konecny", 96),
player.Player("Laika", 93),
player.Player("Vivi", 16),
player.Player("Jorts", 75),
player.Player("Yuki", 23),
player.Player("Konecny", 96)
]
homeRoster = [
player.Player("Landeskog", 92),
player.Player("Byram", 4),
player.Player("MacKinnon", 29),
player.Player("Makar", 8),
player.Player("Rantanen", 96),
player.Player("Landeskog", 92),
player.Player("Byram", 4),
player.Player("MacKinnon", 29),
player.Player("Makar", 8),
player.Player("Rantanen", 96)
]
aTeam = team.Team(awayRoster, [player.Player('Artemis', 17)], "Jorts Butter", "BTR")
hTeam = team.Team(homeRoster, [player.Player('Kuemper', 35)], "Colorado Avalanche", "COL")
self.Game = game.Game(aTeam, hTeam)
def faceoffTest(self):
for i in range(0,8):
self.Game.playStopped = True
foResult = self.Game.event()
pass

View file

@ -128,4 +128,20 @@ class RinkGraph(object):
for otherNodeName, nodeDic in allConnected.items():
if nodeDic['adjacent']:
adjacents.append(otherNodeName)
return adjacents
return adjacents
def shotDanger(self, nodeName):
"""Returns an int indicating the danger of a shot from that zone. 0 is no danger, 100 is 26-Offensive Low Slot"""
if isinstance(nodeName, int):
nodeName = str(nodeName)
if int(nodeName[1]) < 5:
return 0
elif nodeName == '26':
return 100
elif nodeName == '25':
return 70
elif nodeName[0] in ['1','3'] or nodeName == '27': #27 is included for tuck/michigan
return 40
else:
return 20