파이썬/파이썬(python) 중급

[24-3 파이썬] 뱀 게임 만들기 5(파일 저장하고 불러오기)

Olivia-BlackCherry 2022. 9. 4. 08:28

업무 자동화에 가장 기본이 되는 파이썬 기능인

파이썬 with키워드를

 

지난 시간에 만들어 놓은

뱀 게임 만들기 코드로

실습해보겠다.

최종화면

 

(선수학습)

1. with키워드를 이용해 파일을 열고, 닫는 방법, 파일 모드 a, w, r에 대해

복습하고 싶다면  ----->클릭

2. 뱀 게임 만들기 마지막 코드를 보고싶다면 ----->클릭

 

 

오늘의 미션을 해결해보자. 

1. 최고점수를 기록한다.
2. 게임을 종료하고 다시 열어도, 최고점수는 변하지 않고 기록되어 있다.
최종화면

 

해결 방법은 총 2가지로 제시해본다. 

이것말고도 또 다른 방법이 있을 수 있다는 것을 미리 밝힌다.

 

첫 번째 방법

1. with 키워드 이용해서 high_score.txt파일 생성하고, 0을 입력한다. 

파일을 생성하고 나서는 메인 코드에서는 아래 코드를 삭제해준다. 

왜냐하면 이것을 그대로 놔두면 

프로그램이 실행될 때마다 high_score.txt 안의 값이 0으로 덮어써지기 때문이다.

with open("high_score.txt", mode="w") as file:
    past_high_score = file.write("0")

 

2. high_score.txt에서 파일을 읽어오고, 해당 값을 past_high_score로 정한다. 

참고로 데이터타입이 문자형이므로 int함수를 이용해서 정수형으로 바꿔준다.

Scoreboard 클래스에서 객체를 생성할 때 argument로 past_high_score를 입력받는다.

main.py

with open("high_score.txt", mode="r") as file:
    past_high_score = file.read()
    past_high_score = int(past_high_score)

scoreboard = Scoreboard(past_high_score)

 

3. Scoreboard 클래스의 init함수에서 self.high_score의 값을 past_high_score로 바꾼다.

def __init__(self, past_high_score):
    super().__init__()
    self.score = 0
    # 최고 점수 변수를 만든다.
    self.high_score = past_high_score
    self.color("white")
    self.penup()
    self.goto(0, 270)
    self.hideturtle()
    self.update_scoreboard()

 

4. change_high_score의 함수를 정의한다.

high_score.txt 안의 값을 경신한 최고점수로 바꾸는 의미이다.

def change_high_score(self):
    with open("high_score.txt", mode="w") as file:
        file.write(f"{self.high_score}")

 

5. 기존의 reset함수를 수정한다.

high_score의 변경이 발생하면, change_high_score()함수를 호출한다.

def reset(self):
    if self.score > self.high_score:
        self.high_score = self.score
        self.change_high_score()
    self.score = 0
    self.update_scoreboard()

 

<최종코드>

main.py

from turtle import Screen
from snake import Snake
from food import Food
from scoreboard import Scoreboard
import time

screen = Screen()
screen.setup(width=600, height=600)
screen.bgcolor("black")
screen.title("My Snake Game")
screen.tracer(0)

snake = Snake()
food = Food()

with open("high_score.txt", mode="w") as file:
    past_high_score = file.write("0")
    past_high_score = int(past_high_score)

scoreboard = Scoreboard(past_high_score)

with open("high_score.txt", mode="r") as file:
    past_high_score = file.read()
    past_high_score = int(past_high_score)

scoreboard = Scoreboard(past_high_score)



screen.listen()
screen.onkey(snake.up, "Up")
screen.onkey(snake.down, "Down")
screen.onkey(snake.left, "Left")
screen.onkey(snake.right, "Right")

game_is_on = True
while game_is_on:
    screen.update()
    time.sleep(0.1)
    snake.move()

    #Detect collision with food.
    if snake.head.distance(food) < 15:
        food.refresh()
        snake.extend()
        scoreboard.increase_score()

    #Detect collision with wall.
    if snake.head.xcor() > 280 or snake.head.xcor() < -280 or snake.head.ycor() > 280 or snake.head.ycor() < -280:
        # 점수판에 점수를 기록하고, 뱀을 다시 생성한다.
        scoreboard.reset()
        snake.reset()

    #Detect collision with tail.
    for segment in snake.segments:
        if segment == snake.head:
            pass
        elif snake.head.distance(segment) < 10:
            # 점수판에 점수를 기록하고, 뱀을 다시 생성한다.
            scoreboard.reset()
            snake.reset()

screen.exitonclick()

 

Scoreboard.py

from turtle import Turtle

ALIGNMENT = "center"
FONT = ("Courier", 24, "normal")

class Scoreboard(Turtle):

    def __init__(self, past_high_score):
        super().__init__()
        self.score = 0
        # 최고 점수 변수를 만든다.
        self.high_score = past_high_score
        self.color("white")
        self.penup()
        self.goto(0, 270)
        self.hideturtle()
        self.update_scoreboard()

    def update_scoreboard(self):
        self.clear()
        self.write(f"Score: {self.score}  high_score:{self.high_score}", align=ALIGNMENT, font=FONT)

    # 리셋 함수를 만든다.
    def reset(self):
        if self.score > self.high_score:
            self.high_score = self.score
            self.change_high_score()
        self.score = 0
        self.update_scoreboard()

    def increase_score(self):
        self.score += 1
        self.clear()
        self.update_scoreboard()

    def change_high_score(self):
        with open("high_score.txt", mode="w") as file:
            file.write(f"{self.high_score}")


 

 

 

두 번째 방법

이번에는 main.py는 수정하지 않고, scoreboard.py에서만 코드를 수정해보겠다. 

훨씬 단순하고 깔끔하다. 

 

1. Scoreboard 클래스의 init함수에서 high_score.txt를 바로 불러와 그 값을

정수형으로 바꾼 다음,

self.high_score에 저장한다.

def __init__(self):
    super().__init__()
    self.score = 0
    with open("high_score.txt", mode="r") as file:
        self.high_score = int(file.read())
    self.color("white")
    self.penup()
    self.goto(0, 270)
    self.hideturtle()
    self.update_scoreboard()

 

2. reset함수 안에서  with 키워드를 써서

high_score.txt 파일에 새로운 self.high_score 값을 덮어쓴다.

def reset(self):
    if self.score > self.high_score:
        self.high_score=self.score
        with open("high_score.txt", mode="w") as file:
            file.write(f"{self.high_score}")
    self.score = 0
    self.update_scoreboard()

 

<최종코드>

from turtle import Turtle
ALIGNMENT = "center"
FONT = ("Courier", 24, "normal")


class Scoreboard(Turtle):

    def __init__(self):
        super().__init__()
        self.score = 0
        with open("high_score.txt", mode="r") as file:
            self.high_score = int(file.read())
        self.color("white")
        self.penup()
        self.goto(0, 270)
        self.hideturtle()
        self.update_scoreboard()

    def update_scoreboard(self):
        self.clear()
        self.write(f"Score: {self.score}  high_score:{self.high_score}", align=ALIGNMENT, font=FONT)


    def reset(self):
        if self.score > self.high_score:
            self.high_score=self.score
            with open("high_score.txt", mode="w") as file:
                file.write(f"{self.high_score}")
        self.score = 0
        self.update_scoreboard()


    def increase_score(self):
        self.score += 1
        self.clear()
        self.update_scoreboard()