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ヤードを超えるすべての長さに対して2つのパットと5以下の長さに対して1つのパットを使用するプット関数を定義します。また、「チップイン」と呼ばれる穴にボールを直接打つためのオプションも含まれています。
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と呼ばれる配列を合計することで、水にヒットするペナルティを追加します。これは、コースのすべてのホールでフェアウェイが常に水またはグリーンにつながるという事実を利用しています。フェアウェイの真ん中にラフが含まれているコースでは変更する必要があります。
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
メインコードが実行された後、条件は、ホール中にボールがあった距離を見て、ボールの状態を報告します。メインプログラムでボールを水に打ち込むのを扱った方法のために、私は状態に関する1つの問題に遭遇しました。プログラムでは、ボールが水に当たった場合、すぐにショットが当たった場所に戻りました。ボールが戻った後に距離が記録されたため、ボールの状態が「水」になることはありません。ホール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
これが、穴をロードしてゲームをプレイするコードの主要部分です。いくつかの条件を初期化した後、コードは「ストローク」を実行して、ボールをホールに向けて打撃します。水に遭遇すると、ペナルティーカウンターに追加され、プログラムwaterが実行され、ボールがヒットした場所に戻されます。緑に出会うと、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
これは多くの試験の中で最も低いスコアの1つであり、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
前に使用したクラブが砂くさびではなかった場合、水に遭遇した後、後方ではなく少量でボールを前方に打とうとするように水の論理を変更することで、1つでテストした後、平均を40.5に、中央値を39に改善しました百万回の実行。最小23、最大135。時には幸運になることもあれば、そうでないこともあります。新しいヒストグラムを確認してください。