Python 2.7:43张平均40.5张照片
这是我在这里的第一篇文章,所以请多多包涵。
由于发帖者考虑将其视为编程挑战,而不是编码高尔夫球,因此我将其视为编程挑战。我试图使我的解决方案和射击逻辑保持简单,但是随着事情的迅速复杂化,结果变得更加难看。
我的密码
阅读时需要注意一些事项:程序创建了一个使用的球杆列表,称为“球杆”,以及一个列表“距离”,即球从发球区经过的距离,hlen是孔的长度,d1s是球的长度。每次射击的距离。
首先,我定义课程。必须定义每个球道,水和果岭的长度,以便以后程序可以检查球的状况,因此我为课程中不存在的部分添加了非整数值。
from random import randint
import numpy as np
#Hole Length flen wlen glen Name
hole1 = [ 401, 54, 390, 390.5, 390.5, 391, 425, 'Hole 1']
hole2 = [ 171, 0.5, 0.5, 1, 165, 166, 179, 'Hole 2']
hole3 = [ 438, 41, 392, 393, 420, 421, 445, 'Hole 3']
hole4 = [ 553, 30, 549, 282, 353, 550, 589, 'Hole 4']
hole5 = [ 389, 48, 372, 1.5, 1.5, 373, 404, 'Hole 5']
hole6 = [ 133, 0.5, 0.5, 1.5, 1.5, 125, 138, 'Hole 6']
hole7 = [ 496, 37, 413, 414, 484, 484, 502, 'Hole 7']
hole8 = [ 415, 50, 391, 1.5, 1.5, 392, 420, 'Hole 8']
hole9 = [ 320, 23, 258, 259, 303, 304, 327, 'Hole 9']
holes = [hole1, hole2, hole3, hole4, hole5, hole6, hole7, hole8, hole9]
在这里,我定义了选择俱乐部的主要逻辑。该程序尝试通过选择长度大于最大发球杆距离的所有长度的发球杆来最大化距离,并选择球杆的范围,该范围包含到球洞的距离。这要求球杆输入所提供的范围是连续的,即击球距离没有间隙。切合实际的要求,因为一个人可以在没有完全后摆的情况下击打球杆,以将其射门距离限制在第二强的球杆的最大距离上。
def stroke(distance):
Length = abs(hlen - distance)
if Length >= Driver_a:
club = 'Driver'
d = randint(Driver_a,Driver_b)
elif Length >= Wood3_a and Length <= Wood3_b:
club = '3-Wood'
d = randint(Wood3_a,Wood3_b)
elif Length >= Wood5_a and Length <= Wood5_b:
club = '5-Wood'
d = randint(Wood5_a,Wood5_b)
elif Length >= Iron3_a and Length <= Iron3_b:
club = '3-Iron'
d = randint(Iron3_a,Iron3_b)
elif Length >= Iron4_a and Length <= Iron4_b:
club = '4-Iron'
d = randint(Iron4_a,Iron4_b)
elif Length >= Iron5_a and Length <= Iron5_b:
club = '5-Iron'
d = randint(Iron5_a,Iron5_b)
elif Length >= Iron6_a and Length <= Iron6_b:
club = '6-Iron'
d = randint(Iron6_a,Iron6_b)
elif Length >= Iron7_a and Length <= Iron7_b:
club = '7-Iron'
d = randint(Iron7_a,Iron7_b)
elif Length >= Iron8_a and Length <= Iron8_b:
club = '8-Iron'
d = randint(Iron8_a,Iron8_b)
elif Length >= Iron9_a and Length <= Iron9_b:
club = '9-Iron'
d = randint(Iron9_a,Iron9_b)
elif Length >= Pwedge_a and Length <= Pwedge_b:
club = 'P wedge'
d = randint(Pwedge_a,Pwedge_b)
elif Length >= Swedge_a and Length <= Swedge_b:
club = 'S wedge'
d = randint(Swedge_a,Swedge_b)
elif Length >= Lwedge_a and Length <= Lwedge_b:
club = 'L wedge'
d = randint(Lwedge_a,Lwedge_b)
else : print 'stroke error'
return club, d
接下来,我定义一个推杆功能,其中所有长度大于5码的推杆都插入孔中,一个推杆的长度等于或小于5码。我还提供了将球直接击入称为“切入”的孔的选项。
def putt(distance):
Length = abs(hlen - distance)
if Length > 5:
club = '2 putts'
elif Length == 0:
club = 'chip in'
else:
club = '1 putt'
return club
这是该策略变得有点时髦的地方。为了保持简单性,并防止陷入水中的循环,只是将球丢到前一杆的位置,然后再次进入水中,我实际上是回溯,用沙楔和然后让代码再次评估镜头,希望是在水面前拍摄,以便下次拍摄可以清除它。这种策略会受到粗暴的惩罚,但是对于清除水是有效的。
def water():
club = 'S wedge'
d = randint(50,79)
return club, d
在打完该孔后,此程序将计算每个孔的笔划数。它通过在每个注水之后追加一个称为water的数组来求和,从而增加了对粗射的惩罚,并添加了对射入水中的惩罚。这利用了这样的事实:球道在路线中的每个孔处总是引水或引向果岭。对于球道中部崎courses不平的球场,必须对其进行更改。
def countstrokes(clubs, distances, waters):
distances = np.array(distances)
mask1 = distances < flen1
mask2 = distances > grn2
extra = sum(mask1*1)+sum(mask2*1) + sum(waters)
if clubs[-1] == 'chip in' : strokes = len(clubs)-1+extra
elif clubs[-1] == '2 putts' : strokes = len(clubs) +1+extra
elif clubs[-1] == '1 putt' : strokes = len(clubs)+extra
else : print 'strokes error'
return strokes
在运行主代码后,条件将检查球在洞中的距离并报告球的状态。由于我在主程序中将球击入水中的处理方式,我遇到了一个条件问题。在程序中,如果将球击入水中,则会立即将其移回击球的位置。该距离是在球移回后记录的,因此球的状态不能为“水”。如果您将球从洞4的发球区击中,则程序会打印出您击中球和球杆的距离,但到洞的长度将保持不变,并且条件将是“粗糙”的,因为将球放在0距离,这是粗略的。您可以取消注释打印“水”
def condition(distances):
conditions=[]
for distance in distances:
if distance >= grn1 and distance <= grn2:
conditions.append('green')
elif distance >= flen1 and distance <= flen2:
conditions.append('fair')
else:
conditions.append('rough')
return conditions
这是加载漏洞并玩游戏的代码的主要部分。初始化某些条件后,代码将“击中”球击向球洞,如果球洞被击球,则反向击球,直到遇到水或果岭为止。如果遇到水,它将添加到罚分计数器并运行程序水,然后将球移回被击中的位置。如果遇到绿色,则调用put并终止该孔。在对距离和球杆进行分析以确定每个击球的状况之后,再对这些击球进行计数。
def golf(driver_a, driver_b, wood3_a, wood3_b, wood5_a, wood5_b, iron3_a, iron3_b, iron4_a, iron4_b, iron5_a, iron5_b, iron6_a, iron6_b, iron7_a, iron7_b, iron8_a, iron8_b, iron9_a, iron9_b, pwedge_a, pwedge_b, swedge_a, swedge_b, lwedge_a, lwedge_b):
global Driver_a, Driver_b, Wood3_a, Wood3_b, Wood5_a, Wood5_b, Iron3_a, Iron3_b, Iron4_a, Iron4_b, Iron5_a, Iron5_b, Iron6_a, Iron6_b, Iron7_a, Iron7_b, Iron8_a, Iron8_b, Iron9_a, Iron9_b, Pwedge_a, Pwedge_b, Swedge_a, Swedge_b, Lwedge_a, Lwedge_b
Driver_a, Driver_b, Wood3_a, Wood3_b, Wood5_a, Wood5_b, Iron3_a, Iron3_b, Iron4_a, Iron4_b, Iron5_a, Iron5_b, Iron6_a, Iron6_b, Iron7_a, Iron7_b, Iron8_a, Iron8_b, Iron9_a, Iron9_b, Pwedge_a, Pwedge_b, Swedge_a, Swedge_b, Lwedge_a, Lwedge_b = driver_a, driver_b, wood3_a, wood3_b, wood5_a, wood5_b, iron3_a, iron3_b, iron4_a, iron4_b, iron5_a, iron5_b, iron6_a, iron6_b, iron7_a, iron7_b, iron8_a, iron8_b, iron9_a, iron9_b, pwedge_a, pwedge_b, swedge_a, swedge_b, lwedge_a, lwedge_b
totals =[]
for hole in holes:
distance = 0
strokes = 0
clubs = []
distances = []
d1s = []
waters=[]
global hlen, flen1, flen2, wtr1, wtr2, grn1, grn2
hlen, flen1, flen2, wtr1, wtr2, grn1, grn2, name = hole
while True:
club1, d1 = stroke(distance)
clubs.append(club1)
if distance > hlen:
d1 = -d1
distance = distance + d1
d1s.append(d1)
if distance >= wtr1 and distance <= wtr2:
#print 'water'
waters.append(1)
distance = distance - d1
distances.append(distance)
club1, d1 = water()
if distance < wtr1:
d1 = - d1
distance = distance + d1
d1s.append(d1)
clubs.append(club1)
distances.append(distance)
if distance >= grn1 and distance <= grn2:
club1 = putt(distance)
clubs.append(club1)
break
strokes = countstrokes(clubs, distances, waters)
totals.append(strokes)
conditions = condition(distances)
shots = len(d1s)
print name, ':',
for x in xrange(0,shots):
print '{', clubs[x], ',', d1s[x],',', conditions[x],',', hlen-distances[x], '}',
print '{',clubs[-1], '}', '{',strokes ,'}'
print 'Total:', sum(totals), 'shots'
return sum(totals)
代码运行像
golf(300,330,270,299,240,269,220,239,200,219,180,199,160,179,140,159,120,139,100,119,80,99,50,79,0,49)
看起来像这样:
Hole 1 : { Driver , 308 , fair , 93 } { P wedge , 96 , green , -3 } { 1 putt } { 3 }
Hole 2 : { 6-Iron , 166 , green , 5 } { 1 putt } { 2 }
Hole 3 : { Driver , 321 , fair , 117 } { 9-Iron , 105 , green , 12 } { 2 putts } { 4 }
Hole 4 : { Driver , 305 , rough , 553 } { S wedge , -62 , rough , 615 } { Driver , 326 , fair , 289 } { 3-Wood , 293 , green , -4 } { 1 putt } { 8 }
Hole 5 : { Driver , 323 , fair , 66 } { S wedge , 73 , green , -7 } { 2 putts } { 4 }
Hole 6 : { 8-Iron , 125 , green , 8 } { 2 putts } { 3 }
Hole 7 : { Driver , 314 , fair , 182 } { 5-Iron , 181 , green , 1 } { 1 putt } { 3 }
Hole 8 : { Driver , 324 , fair , 91 } { P wedge , 91 , green , 0 } { chip in } { 2 }
Hole 9 : { Driver , 317 , green , 3 } { 1 putt } { 2 }
Total: 31 shots
这是许多试验中最低的分数之一,绝对最低的是100,000次运行中的26次。但即使在第4洞打了8杆,仍然低于标准杆34-36。
我将包含用于查找上述指定俱乐部的游戏分布的代码。
import matplotlib.pyplot as plt
class histcheck(object):
def __init__(self):
self = self
def rungolf(self, n=10000):
results=[]
for x in xrange(0,n):
shots = golf(300,330,270,299,240,269,220,239,200,219,180,199,160,179,140,159,120,139,100,119,80,99,50,79,0,49)
results.append(shots)
self.results = results
def histo(self, n=20):
plt.figure(figsize=(12,12))
plt.hist(self.results, bins=(n))
plt.title("Histogram")
plt.xlabel("Shots")
plt.ylabel("Frequency")
plt.show()
跑步
play = histcheck()
play.rungolf()
play.hist()
给出以下直方图
均值和中位数可以使用
np.mean(play.results)
np.meadian(play.results)
平均约为43,中位数为41。通过简单的镜头优化,对于9个洞来说还算不错。
现在都是你的了
继续复制并调整程序,并使用我的工具对其进行评估,以降低平均拍摄数量。让我知道是否有我没有考虑的情况,或者继续制作高尔夫球版本。我认为最好的程序应该是在许多俱乐部投入中返回最低的平均命中率的程序。我的代码不是最好的选择,但我想我会努力的。
更新资料
def water():
if clubs[-1] =='S wedge':
club = 'S wedge'
d = randint(50,79)
elif clubs[-1] !='S wedge':
club = 'S wedge'
d = -randint(50,79)
else: print 'water error'
return club, d
通过更改水位逻辑,使其在遇到水后尝试将球击向前方而不是向后击球(如果先前使用的球杆不是沙楔,则向后击球),经过一轮测试后,将均值提高到40.5,将中位数提高到39 万次运行。最少23个,最多135个。有时您会很幸运,有时却不会。查看新的直方图。