牌語備忘録 -pygo

あくまでもメモです。なるべくオフィシャルの情報を参照してください。

牌語備忘録 -pygo

『ノン・プログラマのためのPHP入門』のボーリングの得点計算をするスクリプトをPythonでやってみた

ノン・プログラマのためのPHP入門 10日間コース』84ページから

ボーリングの得点計算をするアルゴリズムを考える

1:ピンを倒した数を配列に格納するアルゴリズムを考える

1フレームから10フレームまで繰り返す
1フレーム、最高で3回まで毅げることができるので3回繰り返す(10フレームは
3球投げることができる可能性がある

1投目の場合は10ピンをセットする

■ 10フレームの場合
ランダムで残リビン数の間で数値を求める
現在の投球箇所にピン数をセットする
残リピン数から今求めたピンを引く
残リピン数が0だったら10本を再度セットする
2投目でストライクかスペアを出していない場合は10フレーム終了

■ 10フレームじゃない場合
10フレーム以外は3投目はないので3投目の場合は投球繰り返し終了
ランダムで残リピン数の間で数値を求める
現在の投球箇所にピン数をセットする
残リピン数から今求めたピンを引く


これをPythonでやってみた

#!/usr/local/bin/python
# *-# -*- coding: utf-8 -*-

import random

def tenpin():
   t = []
   for i in range(1,11):
       t.append(i)
   return t

def hitpin(p):
   pin = p
   lenpin = len(pin)
   # "+1" is gutter
   hitnum = random.randrange(lenpin + 1)
   oddpin = random.sample(pin,lenpin - hitnum)
   oddpin.sort()
   return [hitnum, oddpin]

def oneframe(freamnum):
   oneflist = []
   for i in range(3):
       if i == 0:
           pinnum = tenpin()
           oneflist.append(hitpin(pinnum))
       elif i == 1:
           if oneflist[0][0] == 0:
               pass
           pinnum = oneflist[0][1]
           oneflist.append(hitpin(pinnum))
       elif freamnum == 10 and i == 2 and \
            (len(oneflist[0][1]) == 0 or len(oneflist[1][1]) == 0):
           pinnum = tenpin()
           oneflist.append(hitpin(pinnum))
   return oneflist


for i in range(1,11):
   for j in oneframe(i):
       #print j,
       print j[0],
   print

結果

8 1
4 1
9 0
5 4
5 2
4 4
5 4
2 7
1 4
10 0 9

とりあえず動いた。



ちょっと修正変更。
#!/usr/local/bin/python
# *-# -*- coding: utf-8 -*-

import random

def hitpin(pinlist):
   lenpin = len(pinlist)
   hitnum = random.randrange(lenpin + 1) # "+1" is gutter
   leftoverpin = random.sample(pinlist,lenpin - hitnum)
   leftoverpin.sort()
   return [hitnum, leftoverpin]

def oneframe(freamnum):
   initpin = ["1","2","3","4","5","6","7","8","9","10"]
   score = []
   for i in range(2):
       if i == 0:
           pinnum = initpin
       elif i == 1:
           pinnum = score[0][1]
       score.append(hitpin(pinnum))
   if freamnum == 10 and len(score[1][1]) == 0:
      pinnum = initpin
      score.append(hitpin(pinnum))
   return score

if __name__ == "__main__":
   for i in range(1,11):
      for j in oneframe(i):
          #print j,
          print j[0],
      print

結果

8 1
1 1
0 3
5 1
9 1
3 1
7 0
4 4
2 8
10 0 4

あとでもう少し手を入れる予定。


またまた修正変更
#!/usr/local/bin/python
# *-# -*- coding: utf-8 -*-

import random

def hitpin(pinnum):
  hitnum = random.randrange(pinnum + 1) # "+1" is gutter
  return hitnum

def oneframe(freamnum):
  initpin = 10
  score = []
  for i in range(2):
      if i == 0:
          pinnum = initpin
      elif i == 1:
          pinnum = initpin - score[0]
      score.append(hitpin(pinnum))
  if freamnum == 10 and score[0]+score[1] == 10:
     pinnum = initpin
     score.append(hitpin(pinnum))
  return score

def main():
    for i in range(1,11):
        print i
        print oneframe(i)
        
if __name__ == "__main__":
    main()

結果

1
[1, 5]
2
[2, 3]
3
[2, 8]
4
[6, 0]
5
[1, 1]
6
[3, 5]
7
[5, 0]
8
[6, 3]
9
[6, 3]
10
[9, 1, 6]
また、またまた修正変更(たぶん最終形)
#!/usr/local/bin/python
# *-# -*- coding: utf-8 -*-

import random

def hitpin(pinnum):
  hitnum = random.randrange(pinnum + 1) # "+1" is gutter
  return hitnum

def oneframe(freamnum):
  initpin = 10
  score = [hitpin(initpin)]
  score.append(hitpin(initpin - score[0]))
  if freamnum == 10:
      if score[0]+score[1] == 10:
            score.append(hitpin(initpin))
  return score

def main():
    for i in range(1,11):
        print i, oneframe(i)
        
if __name__ == "__main__":
    main()

result

1 [0, 0]
2 [7, 3]
3 [6, 1]
4 [4, 0]
5 [8, 1]
6 [5, 1]
7 [9, 0]
8 [1, 3]
9 [3, 3]
10 [4, 6, 4]

こんなんできました(゚Д゚)