forked from ethan-buckner/darts-engine
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcrick_bot.py
145 lines (116 loc) · 4.02 KB
/
crick_bot.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
import math
import random
import numpy as np
from matplotlib import pyplot as plt
radius = 170
# class to make it easier to convert between cartesian and polar coordinates
class Coord:
radius = 0.0
theta = 0.0
radial = True
x = 0.0
y = 0.0
def __init__(self, radial, rx, ty):
if radial:
self.radius = rx
self.theta = ty
self.x = convertToX(self)
self.y = convertToY(self)
else:
self.x = rx
self.y = ty
self.radius = convertToR(self)
self.theta = convertToTheta(self)
def convertToX(coord):
return coord.radius * math.cos(coord.theta)
def convertToY(coord):
return coord.radius * math.sin(coord.theta)
def convertToR(coord):
return abs(math.sqrt(math.pow(coord.x, 2) + math.pow(coord.y, 2)))
def convertToTheta(coord):
result = math.atan2(coord.y, coord.x)
if result < 0.0:
result += 2 * math.pi
return result
def getValue(target):
if target == 6:
return 25
else:
return target + 15
# default to highest possible scoring target
# strategy 1 which is used by the computer
def findTarget1(state1, state2):
target = 6
for index in range(len(state1) - 3, -1, -1):
if state1[index] < 3:
target = index
break
target = 6
for index in range(len(state2) - 3, -1, -1):
if state2[index] < 3:
target = index
break
return target
# strategy 2
def findTarget2(state1, state2):
target = 6
for index in range(len(state2) - 1, -1, -1):
if state2[index] < 3:
target = index
break
return target
# strategy 3
def findTarget3(state1, state2):
target = 6
for index in range(len(state2) - 1, -1, -1):
if state1[index] == 3 and state2[index] < 3:
target = index
break
return target
tripRadius = 103
targetList = [Coord(True, tripRadius, 9 * math.pi / 5), Coord(True, tripRadius, 6 * math.pi / 5),
Coord(True, tripRadius, 8 * math.pi / 5), Coord(True, tripRadius, 3 * math.pi / 10),
Coord(True, tripRadius, 7 * math.pi / 5), Coord(True, tripRadius, math.pi / 2),
Coord(True, 0, math.pi / 2)]
# calculates if a given coordinate falls within the specified regions 20, 19, 18, 17, 16, 15, bullseye, or multiples
def calculateShot(coord):
result = ""
hit = False
if coord.radius <= radius:
if 9 * math.pi / 20 <= coord.theta <= 11 * math.pi / 20:
result += "20"
hit = True
elif 27 * math.pi / 20 <= coord.theta <= 29 * math.pi / 20:
result += "19"
hit = True
elif 5 * math.pi / 20 <= coord.theta <= 7 * math.pi / 20:
result += "18"
hit = True
elif 31 * math.pi / 20 <= coord.theta <= 33 * math.pi / 20:
result += "17"
hit = True
elif 23 * math.pi / 20 <= coord.theta <= 25 * math.pi / 20:
result += "16"
hit = True
elif 35 * math.pi / 20 <= coord.theta <= 37 * math.pi / 20:
result += "15"
hit = True
if radius >= coord.radius >= radius - 8 and hit:
result += " 2"
elif 107 >= coord.radius >= 107 - 8 and hit:
result += " 3"
elif 16 >= coord.radius:
if coord.radius <= 6.35:
return "25 2"
return "25"
return result
# adds randomality to each throw based on the difficulty setting
def shoot(boardState1, boardState2, difficulty):
target = findTarget1(boardState1, boardState2)
targetCoord = targetList[target]
newX = random.gauss(targetCoord.x, (100 - difficulty) / 3)
newY = random.gauss(targetCoord.y, (100 - difficulty) / 3)
plt.plot(newX, newY, "rx")
newCoord = Coord(False, newX, newY)
result = calculateShot(newCoord)
return result