質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

1回答

487閲覧

Snake Gameのコードについて

TAIniko

総合スコア32

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

1クリップ

投稿2020/05/09 08:32

前提・実現したいこと

こちらのサイトを参考にしました。

130行目からの
self.commandpendingのフラグを一度TrueにしてFalseにもどしていますが、
Snake()の処理を見るかぎり必要なさそうだったのでコメントアウトして実行したところ特に問題なく動きました。
そこで聞きたいのが、
self.commandpendingのフラグを一度TrueにしてFalseにもどす
のは何のために必要なのでしょうか?

該当のソースコード

Python

1from turtle import Turtle, Screen 2import turtle 3import random 4import time 5 6SIZE = 20 # 蛇の大きさ 7 8 9class Square: 10 def __init__(self, x, y): 11 self.x = x 12 13 self.y = y 14 15 def draw_self(self, turtle): 16 turtle.goto(self.x - SIZE // 2, self.y - SIZE // 2 - 1) 17 18 turtle.begin_fill() 19 for _ in range(4): 20 turtle.forward(SIZE - SIZE // 10) # // 商を返す 21 turtle.left(90) 22 turtle.end_fill() 23 24 25class Food: 26 def __init__(self, x, y): 27 self.x = x 28 self.y = y 29 self.is_blinking = True 30 31 def change_location(self): 32 self.x = random.randint(0, SIZE) * SIZE - 200 # Foodの座標をランダムに設定 33 self.y = random.randint(0, SIZE) * SIZE - 200 34 35 def draw_self(self, turtle): 36 if self.is_blinking: 37 turtle.goto(self.x - SIZE // 2 - 1, self.y - SIZE // 2 - 1) 38 turtle.begin_fill() 39 for _ in range(4): 40 turtle.forward(SIZE - SIZE // 10) 41 turtle.left(90) 42 turtle.end_fill() 43 44 def change_state(self): 45 self.is_blinking = not self.is_blinking 46 47 48class Snake: 49 def __init__(self): 50 self.headposition = [SIZE, 0] 51 self.body = [Square(-SIZE, 0), Square(0, 0), Square(SIZE, 0)] 52 self.nextX = 1 53 self.nextY = 0 54 self.crashed = False 55 self.nextposition = [self.headposition[0] + SIZE * self.nextX, self.headposition[1] + SIZE * self.nextY] 56 57 def moveOneStep(self): 58 if Square(self.nextposition[0], self.nextposition[1]) not in self.body: 59 self.body.append(Square(self.nextposition[0], self.nextposition[1])) 60 del self.body[0] 61 self.headposition[0], self.headposition[1] = self.body[-1].x, self.body[-1].y 62 self.nextposition = [self.headposition[0] + SIZE * self.nextX, self.headposition[1] + SIZE * self.nextY] 63 else: 64 self.crashed = True 65 66 def moveup(self): 67 self.nextX, self.nextY = 0, 1 68 69 def moveleft(self): 70 self.nextX, self.nextY = -1, 0 71 72 def moveright(self): 73 self.nextX, self.nextY = 1, 0 74 75 def movedown(self): 76 self.nextX, self.nextY = 0, -1 77 78 def eatFood(self): 79 self.body.append(Square(self.nextposition[0], self.nextposition[1])) 80 self.headposition[0], self.headposition[1] = self.body[-1].x, self.body[-1].y 81 self.nextposition = [self.headposition[0] + SIZE * self.nextX, self.headposition[0] + SIZE * self.nextY] 82 83 def draw_self(self, turtle): 84 for segment in self.body: 85 segment.draw_self(turtle) 86 87 88class Game: 89 def __init__(self): 90 self.screen = Screen() 91 self.artist = Turtle(visible=False) 92 self.artist.up() # up = penup 93 self.artist.speed('slowest') 94 95 self.snake = Snake() 96 self.food = Food(100, 0) 97 self.counter = 0 98 self.commandpending = False 99 100 self.screen.tracer(0) 101 102 self.screen.listen(0) 103 self.screen.onkey(self.snake_down, 'Down') 104 self.screen.onkey(self.snake_up, 'Up') 105 self.screen.onkey(self.snake_left, 'Left') 106 self.screen.onkey(self.snake_right, 'Right') 107 108 def nextFrame(self): 109 self.artist.clear() 110 111 if (self.snake.nextposition[0], self.snake.nextposition[1]) == (self.food.x, self.food.y): 112 self.snake.eatFood() 113 self.food.change_location() 114 else: 115 self.snake.moveOneStep() 116 117 if self.counter == 10: 118 self.food.change_state() 119 self.counter = 0 120 else: 121 self.counter += 1 122 123 self.food.draw_self(self.artist) 124 self.snake.draw_self(self.artist) 125 self.screen.update() 126 self.screen.ontimer(lambda: self.nextFrame(), 100) 127 128 def snake_up(self): 129 if not self.commandpending: 130 # self.commandpending = True 131 self.snake.moveup() 132 # self.commandpending = False 133 134 def snake_down(self): 135 if not self.commandpending: 136 # self.commandpending = True 137 self.snake.movedown() 138 # self.commandpending = False 139 140 def snake_left(self): 141 if not self.commandpending: 142 # self.commandpending = True 143 self.snake.moveleft() 144 # self.commandpending = False 145 146 def snake_right(self): 147 if not self.commandpending: 148 # self.commandpending = True 149 self.snake.moveright() 150 # self.commandpending = False 151 152 153game = Game() 154 155screen = Screen() 156screen.ontimer(lambda: game.nextFrame(), 100) 157screen.mainloop() 158

補足情報(FW/ツールのバージョンなど)

Python 3.7.6

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

大元の出典は他にあるのでしょうか。コードの中身には触れず紹介だけといった感じですね。
"commandpending" で検索すると幾つか同じコードが見つかりました。

turtleでは、マルチスレッドで呼ばれてるわけではないので見た感じ不要です。
else を付け加えても、呼ばれるケースは確認できません。

python

1 if not self.commandpending: 2 self.commandpending = True 3 self.snake.moveright() 4 self.commandpending = False 5 else: 6 print("PENDING")

キー入力時に他の動作が不要なら、以下のように直接指定も可能です。(引数が無い為)

python

1 self.screen.onkey(self.snake.movedown, 'Down') 2 self.screen.onkey(self.snake.moveup, 'Up') 3 self.screen.onkey(self.snake.moveleft, 'Left') 4 self.screen.onkey(self.snake.moveright, 'Right')

参考元のコードがマルチスレッドで、そのまま残ってしまった等が考えられます。
意図としては、スネークの移動中はキー入力を読み飛ばし、もしくは保留。

マルチスレッドの場合は、この様なコードが影響する事もあります。
・・・が、このコードではロックとしての利用だとしては不完全なので、疑問は残ります。

python

1 if not self.commandpending: 2 # **マルチスレッドで(仮定)**、ここのタイミングでフラグ判定されると、 3 # チェックをすり抜ける可能性があるので、ロックとしては不完全。 4 # 再現性の低いバグの原因になるので避けるべきです。 5 self.commandpending = True 6 self.snake.moveright() 7 self.commandpending = False 8 else: 9 print("PENDING")

投稿2020/05/09 12:13

teamikl

総合スコア8664

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

TAIniko

2020/05/10 01:56

大元については記載がないのでわからないです。 マルチスレッドなどは勉強不足でちゃんと理解できていませんが、詳しくありがとうございました! 教えていただいたサイトを参考にもう少ししらべてみます:-)
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問