Thread를 이용하여 경마게임을 만들었다.
프로그램 시작 시 사용자는 말의 마리수를 입력하고, 마리수만큼의 말이 경마를 시작한다. 경마의 진행상황은 1초마다 갱신되어 도착선에 먼저 도착한 경마의 순위를 출력한다.
사용자의 경마는 1번마이며 스페이스바를 누를 시 부스터를 사용할 수 있게 하였다. 또한 경마시간은 실시간으로 출력되게 하였다.
이번 프로그램은 Thread를 공부하는 것이기 때문에 각각의 말을 Thread처리하여 독립적으로 진행되게 하였다.
다음은 말의 이동과 위치를 변경하는 클래스이다
Horse.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
import threading
import random
import time
class Horse(threading.Thread):
def __init__(self):
threading.Thread.__init__(self)
self.location = 0
def run(self):
while True:
self.location += random.randint(1,3)
if self.location > 30:
self.location = 31
break
time.sleep(1)
|
cs |
말의 이동은 랜덤이므로 random모듈을 사용하여 1~3칸의 이동을 랜덤으로 이동하게 하였다. 이동된 위치는 location변수에 저장하고 location변수가 30을 초과할 경우 31칸으로 고정하여 실행을 종료하게 하였다.
Time.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
import threading
import time
class Time(threading.Thread):
def __init__(self):
threading.Thread.__init__(self)
self.endTime = 0
self.resultTime = 0
self.checkEnd = 0
self.startTime = None
def run(self):
self.startTime = time.time() #시작된 시간 체크
while True:
self.endTime = time.time() #현재 측정된 시간 체크
self.resultTime = self.endTime - self.startTime #현재시간 - 시작시간 = 경과된 시간
if self.checkEnd == 1: #모든말이 들어오면 종료
break
time.sleep(0.1)
def printTime(self):
print("현재 경과된 시간은 " + str(round(self.resultTime,2)) + "초 입니다.")
|
cs |
경마진행시간또한 실시간으로 출력되어야 하므로 Thread를 사용하였다. time모듈을 사용하여 시작시간을 체크한 후 0.1초마다 현재시간을 체크하여 둘의 차로 경과된 시간을 간단하게 계산하였다.
Boost.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
import threading
import keyboard
import time
class Boost(threading.Thread):
def __init__(self,horse):
threading.Thread.__init__(self)
self.horse = horse
self.checkEnd = 0
def run(self):
while True:
if keyboard.is_pressed('space'):
if self.horse.location < 30:
print("1번마 부스터!")
self.horse.location += 3
time.sleep(0.5)
if self.checkEnd == 1:
break
|
cs |
부스트를 사용하는 Boost.py를 만들었다. 부스트는 키보드의 스페이스바를 인식하여 스페이스바가 눌리면 부스터가 사용되도록 하였다.
Racing.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
|
import time
from Boost import Boost
from Horse import Horse
from Time import Time
class Racing:
def __init__(self):
self.horseNumber = None
self.horseList = [] #tmp로 객체로 만들어서 넣어주어야함 tmp로 만들때마다 주소값이 새로 지정되기 때문에 값이 공유되지않음
self.nowTime = Time()
self.finish = 0
self.boost = None
self.ranking = []
def starting(self): #경마시작
print("경마장에 오신 것을 환영합니다.")
self.horseNumber = int(input("출전시키실 말의 수를 입력해주세요 : "))
for index in range(self.horseNumber): #입력한 숫자만큼 말 생성
tmpHorse = Horse() # !!!! 주소값 다름1!
self.horseList.append(tmpHorse)
for index2 in range(len(self.horseList)): #등록된 말 모두 위치변경 시작
self.horseList[index2].start()
self.boost = Boost(self.horseList[0])
self.boost.start() #부스터기능 시작
self.nowTime.start() #시간측정시작
while True:
for i in range(7):
print()
self.nowTime.printTime() #경과된 시간 출력
for index2 in range(len(self.horseList)): #인터페이스 출력
print(str(index2+1) +"번마" + " " * self.horseList[index2].location + "🦓")
if self.horseList[index2].location == 31: #먼저들어온 말 랭킹리스트에 추가
self.ranking.append(str(index2+1) + "번마")
for index3 in range(len(self.horseList)): #경마 종료판정
if self.horseList[index3].location == 31:
self.finish = 1
else: # 마지막말이 들어오지못하면 finish는 0으로 바뀜
self.finish = 0
break
if self.finish == 1:
self.nowTime.checkEnd = 1
self.boost.checkEnd = 1
print("경기끝")
self.ranking = list(dict.fromkeys(self.ranking)) #중복제거
for rank in range(len(self.horseList)):
print(str(rank+1)+"위 : " + str(self.ranking[rank]) )
break
time.sleep(1)
class Main:
if __name__ == "__main__" :
racing = Racing()
racing.starting()
|
cs |
게임의 전체적인 실행을 하는 클래스이다.
숫자를 입력받아 입력받은 숫자만큼 horse의 객체를 생성한다. 생성한 객체는 배열에 저장하여 놓는다. 그 후 배열의 크기만큼 Thread의 start를 사용하여 Thread를 시작한다. Thread를 시작한 시점에서 말들의 location은 변하고 있으므로 각각의 말의 location을 불러와 print문으로 출력한다. 이 후 말이 30칸이상 이동하였으면 finish변수를 1번 그렇지않으면 0의 값을 넣어준다. 또한 rank변수에 결승선을 통과한 말을 추가시킨다.
모든말이 결승선을 통과하면 Thread를 정지하고 랭킹을 출력시킨다.
'Python' 카테고리의 다른 글
파이썬 (2) 완성된 스도쿠판 자동생성기 (0) | 2022.05.13 |
---|---|
파이썬 (1) 기본적인 문법 (0) | 2022.05.09 |