심 시뮬레이션

컴퓨터

심 시뮬레이션

20119 이지호 심시뮬 축제 활동

이름 20119 이지호 등록일 25.11.11 조회수 2

<텍스트 오류 있어요.>

 

 

동아리에서 ‘10층 아파트 쌓기’ 게임의 인공지능 모델을 설계하고 구현하였다. C#과 연개해서 Python을 활용하여 사용자와 AI가 번갈아 층수를 선택하는 구조를 만들고, 승패 결과에 따라 전략이 변화하는 간단한 강화학습 알고리즘을 적용하였다. 게임의 상태를 ‘현재 총 층수’로 정의하고, 각 상태에서 선택할 수 있는 행동(1·2·3층)에 점수를 부여하는 방식으로 정책을 구성하였다. 승리 시 해당 선택의 점수를 올리고, 패배 시 점수를 감소시키는 형형태로 보상함수를 설계하였으며, 특정 상황에서 이전 선택까지 연관하여 보정되는 규칙을 추가하여 전략이 누적적으로 학습되도록 했다. 또한 게임 구조를 수학적으로 2층 또는 6층을 먼저 쌓으면 무조건 승리하게되는는 점을 파악하고, 이를 통해 게임 진행의 형평성을 조정하고 모델이 스스로 학습할 수 있도록 점수 업데이트 조건을 실험적으로 조정하였다. 이를 통해 단순한 난수형 플레이가 아닌, 플레이가 반복될수록 AI가 점차 최적 전략에 수렴해 가는 과정을 구현하였다. 이 활동을 통해 강화학습의 기본 개념인 상태-행동 가치 업데이트, 보상 설계, 탐색과 활용의 균형 등을 직접 다루어 보았고, 파이썬 프로그래밍 능력뿐 아니라 알고리즘을 논리적으로 구성하는 사고력과 ?수학적 모델링 능력을 함께 기를 수 있었다. 또 모둠활동을 하며 의논하고 합의하며, 동아리 발표회에서 강화학습 모델에 대한 원리를 설명하고 시연했다.

 

 활동내용ㅇ:

작동방식: 사용자 선으로 컴퓨터와 사용자간 턴제 게임. 10을 먼저 쌓으면 승리컴퓨터는 사용자가 만든 전체 층수를 클래스로 하고 각 클래스마다 1,2,3이 있는데 10점으로 기본 점수를 가짐. 어떤 클래스에서 점수가 가장 높은 수를 층수로 쌓는다. 하지만 가장 높은 점수가 같은 것이 있을 경우 그것들 중에 랜덤으로 고른다. 사용자가 먼저 10층 완성시에는 컴퓨터가 마지막에 쌓았던 수의 점수를 ,1,반대로 컴퓨터가 먼저 10층 완성시 마지막에 +1, 단 어떤 수의 점수가 12점 이상이고 +1점 획득시에는 이전에 두었던 수의 점수도 같이 +1, 반대로는 점수가 8점 이하이고 ,1점 획득시에는 이전에 두었던 수의 점수도 ,1. 참고로 게임 특성상 2점, 6점을 먼저 만드는 사람이 승리!

 

import random
import time
# GIST 점수판 초기화
gist_scores = {total: {n: 10 for n in range(1, 4)} for total in range(1, 10)}
user_total_score = 0
gist_total_score = 0
game_round = 1

print("?? 10층 아파트 쌓기 게임 ??")
time.sleep(1)
print('\nXX 연타 하지 마세요 XX\n')
time.sleep(1.5)
print("게임 규칙:")
print("- 당신과 GIST(Game Intelligence & Strategy Trainer) 모델이 번갈아 1,2,3층 중 하나를 선택하여 총합 10층을 쌓습니다.")
time.sleep(2)
print("- 당신이 먼저 10층을 쌓으면 승리합니다.")
time.sleep(2)
print("- GIST 모델은 게임 결과에 따라 점수를 학습하며 전략이 발전합니다.")
time.sleep(2)
print("- 사용자는 첫 번째 턴에 2층을 쌓을 수 없습니다!")
time.sleep(2)
print("- 10층을 초과하면 안 됩니다.")
time.sleep(2)
# 사용자에게 GIST 이름 짓기
gist_name = input("?? 당신이 상대할 GIST 모델에게 이름을 지어주세요: ").strip()
if not gist_name:
    gist_name = "GIST"
print(f"\n좋습니다! 이제부터 당신의 상대방은 '{gist_name}'입니다. 행운을 빕니다!\n")
print('로딩중')
for i in range(3):
    print('.',end=' ')
    time.sleep(0.5)
   
# 게임 시작
while True:
    print(f"\n==== 게임 {game_round} 시작 ====")
    total = 0
    turn = "USER"
    gist_history = []
    first_user_turn = True
    while True:
        print(f"\n  <층수: {total}>")

        if turn == "USER":
            while True:
                try:
                    time.sleep(0.5)
                    print()
                    user_input = int(input("쌓을 층수를 고르세요(1,2,3층): "))
                    if user_input not in [1, 2, 3]:
                        print()
                        print("?? 1, 2, 3층 중 하나만 선택할 수 있습니다.")
                        continue
                    if first_user_turn and user_input == 2:
                        print()
                        print("?? 첫 턴에는 2층을 쌓을 수 없습니다.")
                        continue
                    if total + user_input > 10:
                        print()
                        print("?? 총 층수가 10층을 넘을 수 없습니다.")
                        continue
                    break
                except ValueError:
                    print()
                    print("?? 잘못된 입력입니다.")

            total += user_input
            first_user_turn = False

            if total == 10:
                print('  <10층 달성!!>')
                print("?? 당신의 승리! ??")
                user_total_score += 1
                # GIST가 지면 마지막 선택 점수 -1
                if gist_history:
                    last_total, last_choice = gist_history[-1]
                    gist_scores[last_total][last_choice] -= 1
                    if gist_scores[last_total][last_choice] <= 8 and len(gist_history) >= 2:
                        prev_total, prev_choice = gist_history[-2]
                        gist_scores[prev_total][prev_choice] -= 1
                break

            turn = gist_name

        else:  # GIST 턴
            if total not in gist_scores:
                print(f"{gist_name}는 더 이상 선택할 수 없습니다.")
                break

            possible_choices = [n for n in range(1, 4) if total + n <= 10]
            max_score = max(gist_scores[total][n] for n in possible_choices)
            best_choices = [n for n in possible_choices if gist_scores[total][n] == max_score]
            choice = random.choice(best_choices)       # 동점이면 랜덤 선택
            print()
            print('   -생각중...')
            time.sleep(0.6)
            print()
            print(f"?? {gist_name}는 {choice} 층을 쌓았습니다.")
            print()
            time.sleep(0.8)
            gist_history.append((total, choice))
            total += choice

            if total == 10:
                print('  <10층 달성!!>')
                print(f"?? {gist_name} 승리! ??")
                gist_total_score += 1
                last_total, last_choice = gist_history[-1]
                gist_scores[last_total][last_choice] += 1
                if gist_scores[last_total][last_choice] >= 12 and len(gist_history) >= 2:
                    prev_total, prev_choice = gist_history[-2]
                    gist_scores[prev_total][prev_choice] += 1
                break

            turn = "USER"

    # 한 판 종료 후 결과 출력
    print(f"\n?? 게임 {game_round} 종료!")
    time.sleep(0.8)
    print(f" ?? 당신의 총 승점: {user_total_score}")
    print(f" ?? {gist_name} 총 승점: {gist_total_score}")

    print("\n?? GIST 전략 점수판:")
    for total in range(1, 10):
        print(f"총 층수 {total} => ", end="")
        for n in range(1, 4):
            print(f"{n}: {gist_scores[total][n]}", end="  ")
        print()
    time.sleep(0.8)
    # 계속 여부 확인
    while True:
        again = input("\n계속 하시겠습니까? (y/n): ").strip().lower()
        if again == 'y':
            game_round += 1
            break
        elif again == 'n':
            print(f'\n당신의 간식 점수... ==>>  {user_total_score}')
            if user_total_score>=15:    #최고점수가 14점: 혹시 이 점수를 넘는 학생은 큰 간식 제공!
                print('축하드립니다! 당신은 제작자의 최고점수를 넘으셨습니다!!')
            elif user_total_score>=10:  #마이쮸+다른 간식
                print('훌룡합니다! 맛있는 간식 챙기세요!')
            else:                       #얻은 점수를 마이쮸 개수로..
                print('인간 시대의 끝이 도래했다...')
            print("\n?? 지금까지 GIST 모델 강화학습 게임이였습니다! 감사합니다!")
            input('키로 종료="">')
            exit()
        else:
            print("y 또는 n으로 입력해주세요.")</enter키로>
다음글 보고서