파이썬 2.7 : 43 40.5 발의 평균
이것은 여기의 첫 번째 게시물이므로 나와 함께하십시오.
포스터는 이것을 코드 골프가 아닌 프로그래밍 문제로 취급하려고 생각했기 때문에 프로그래밍 문제로 다루었습니다. 나는 솔루션을 유지하고 논리를 간단하게 유지하려고 시도했지만 일이 빨리 복잡 해져서 더 추악한 것으로 판명되었습니다.
내 코드
읽을 때 고려해야 할 사항 :이 프로그램은 '클럽'이라는 클럽 목록과 볼이 티에서 이동 한 거리 인 '거리'라는 목록을 생성합니다. 각 샷이 이동하는 거리.
먼저 코스를 정의합니다. 각 페어웨이, 물 및 녹색 길이를 정의해야 나중에 프로그램에서 볼의 상태를 확인할 수 있으므로 존재하지 않는 코스 부분에 정수가 아닌 값을 추가했습니다.
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 개와 홀 1 개를 퍼팅하는 퍼팅 함수를 정의합니다. 또한 'chip in'이라는 구멍에 공을 직접 치는 옵션도 포함되어 있습니다.
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
이 프로그램은 해당 홀이 재생 된 후 홀당 스트로크 수를 계산합니다. 러프에서 샷에 대한 처벌을 추가하고 각 워터 샷 후에 추가되는 물이라는 배열을 합산하여 물에 부딪히는 것에 대한 처벌을 추가합니다. 이것은 페어웨이가 항상 코스의 모든 구멍에 대해 물이나 녹색으로 이어진다는 사실을 이용합니다. 페어웨이 중간에 거친 코스가 있으면 변경해야합니다.
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)
간단한 샷 최적화로 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. 때로는 운이 좋으며 때로는 그렇지 않습니다. 새로운 히스토그램을 확인하십시오.