<?xml version="1.0"?>
<rss version="2.0">
   <channel>
      <title>원당중학교 디지털 새싹 by 박건우</title>
      <link>https://padlet.com/jdes2/kz4evb76orqzh2jj</link>
      <description></description>
      <language>en-us</language>
      <pubDate>2025-10-13 12:51:07 UTC</pubDate>
      <lastBuildDate>2025-11-02 02:50:02 UTC</lastBuildDate>
      <webMaster>hello@padlet.com</webMaster>
      <image>
         <url></url>
      </image>
      <item>
         <title>1. 아두이노 ide 다운로드 파일</title>
         <author>snue0108</author>
         <link>https://padlet.com/jdes2/kz4evb76orqzh2jj/wish/3629701444</link>
         <description><![CDATA[]]></description>
         <enclosure url="https://padlet-uploads-usc1.storage.googleapis.com/2266957732/e95895f6820c18334d80b7f8057a598c/arduino_ide_2_3_6_Windows_64bit.exe" />
         <pubDate>2025-10-13 12:52:41 UTC</pubDate>
         <guid>https://padlet.com/jdes2/kz4evb76orqzh2jj/wish/3629701444</guid>
      </item>
      <item>
         <title>구글 colab</title>
         <author>snue0108</author>
         <link>https://padlet.com/jdes2/kz4evb76orqzh2jj/wish/3629779728</link>
         <description><![CDATA[]]></description>
         <enclosure url="https://colab.google/" />
         <pubDate>2025-10-13 13:38:37 UTC</pubDate>
         <guid>https://padlet.com/jdes2/kz4evb76orqzh2jj/wish/3629779728</guid>
      </item>
      <item>
         <title>프로젝트 팀구성하기</title>
         <author>snue0108</author>
         <link>https://padlet.com/jdes2/kz4evb76orqzh2jj/wish/3629788472</link>
         <description><![CDATA[]]></description>
         <enclosure url="https://docs.google.com/spreadsheets/d/1pXjEOTkOYXPtn-8eTLfZCnZx9kSYJeeWvetfnNe6D_M/edit?usp=sharing" />
         <pubDate>2025-10-13 13:43:35 UTC</pubDate>
         <guid>https://padlet.com/jdes2/kz4evb76orqzh2jj/wish/3629788472</guid>
      </item>
      <item>
         <title></title>
         <author>snue0108</author>
         <link>https://padlet.com/jdes2/kz4evb76orqzh2jj/wish/3633201837</link>
         <description><![CDATA[]]></description>
         <enclosure url="https://form.kosac.re.kr/v/3yzQ5AMHj88ndqPgVOad" />
         <pubDate>2025-10-15 06:30:15 UTC</pubDate>
         <guid>https://padlet.com/jdes2/kz4evb76orqzh2jj/wish/3633201837</guid>
      </item>
      <item>
         <title>구구단 코드</title>
         <author></author>
         <link>https://padlet.com/jdes2/kz4evb76orqzh2jj/wish/3633292157</link>
         <description><![CDATA[<p><br/></p><p>for i in range(2, 10):</p><p>    print(f"[ {i}단 ]")</p><p>    for j in range(1, 10):</p><p>        print(f"{i} x {j} = {i * j}")</p><p>    print()</p><p><br/></p>]]></description>
         <enclosure url="" />
         <pubDate>2025-10-15 07:24:57 UTC</pubDate>
         <guid>https://padlet.com/jdes2/kz4evb76orqzh2jj/wish/3633292157</guid>
      </item>
      <item>
         <title></title>
         <author></author>
         <link>https://padlet.com/jdes2/kz4evb76orqzh2jj/wish/3633292993</link>
         <description><![CDATA[<p>for dan in range(2, 10):</p><p>    for i in range(1, 10):</p><p>        print(f"{dan}*{i}={dan*i}", end=', ' if not (dan <mark> 9 and i </mark> 9) else '\n')</p>]]></description>
         <enclosure url="" />
         <pubDate>2025-10-15 07:25:27 UTC</pubDate>
         <guid>https://padlet.com/jdes2/kz4evb76orqzh2jj/wish/3633292993</guid>
      </item>
      <item>
         <title>구구단 코드</title>
         <author></author>
         <link>https://padlet.com/jdes2/kz4evb76orqzh2jj/wish/3633303462</link>
         <description><![CDATA[<pre><code class="language-python">for dan in range(2, 10):
    print(f"--- {dan}단 ---")
    for i in range(1, 10):
        result = dan * i
        print(f"{dan} x {i} = {result}")
    print()</code></pre>]]></description>
         <enclosure url="" />
         <pubDate>2025-10-15 07:32:30 UTC</pubDate>
         <guid>https://padlet.com/jdes2/kz4evb76orqzh2jj/wish/3633303462</guid>
      </item>
      <item>
         <title>11014 정서우</title>
         <author></author>
         <link>https://padlet.com/jdes2/kz4evb76orqzh2jj/wish/3633310038</link>
         <description><![CDATA[<pre><code class="language-python">for i in range(1, 10):
    for j in range(2, 10):
        print(f"{j} x {i} = {j*i:2d}", end="\t")
    print()</code></pre>]]></description>
         <enclosure url="" />
         <pubDate>2025-10-15 07:37:01 UTC</pubDate>
         <guid>https://padlet.com/jdes2/kz4evb76orqzh2jj/wish/3633310038</guid>
      </item>
      <item>
         <title>구구단 게임1</title>
         <author></author>
         <link>https://padlet.com/jdes2/kz4evb76orqzh2jj/wish/3633315121</link>
         <description><![CDATA[<p>import random</p><p>import time</p><p>import threading</p><p>import sys</p><p>import os</p><p>score = 0</p><p>goal = 15</p><p>time_limit = 5</p><p>ranking_file = "ranking.txt"</p><p>def clear():</p><p>    os.system('cls' if <a rel="noopener noreferrer nofollow" href="http://os.name">os.name</a> == 'nt' else 'clear')</p><p>def load_best():</p><p>    if not os.path.exists(ranking_file):</p><p>        return ("없음", 0)</p><p>    with open(ranking_file, "r", encoding="utf-8") as f:</p><p>        line = f.readline().strip().split(',')</p><p>        if len(line) == 2:</p><p>            return (line[0], int(line[1]))</p><p>    return ("없음", 0)</p><p>def save_best(name, score):</p><p>    with open(ranking_file, "w", encoding="utf-8") as f:</p><p>        f.write(f"{name},{score}")</p><p>def countdown(limit, stop_event):</p><p>    for i in range(limit, 0, -1):</p><p>        if stop_<a rel="noopener noreferrer nofollow" href="http://event.is">event.is</a>_set():</p><p>            return</p><p>        sys.stdout.write(f"\r남은 시간: {i}초 | 현재 점수: {score}")</p><p>        sys.stdout.flush()</p><p>        time.sleep(1)</p><p>    print("\r시간 초과!                    ")</p><p># 게임 시작</p><p>clear()</p><p>print("=== 구구단 스피드 챌린지 ===")</p><p>print("5초 안에 답하라. 2초마다 1점씩 깎인다.")</p><p>print("15점 도달 시 승리.\n")</p><p>name = input("이름 입력: ")</p><p>best_name, best_score = load_best()</p><p>print(f"현재 최고 기록: {best_name} ({best_score}점)\n")</p><p>time.sleep(1)</p><p>clear()</p><p>while score &lt; goal:</p><p>    # 난이도 조정</p><p>    if score &gt;= 10:</p><p>        time_limit = 3</p><p>    elif score &gt;= 5:</p><p>        time_limit = 4</p><p>    else:</p><p>        time_limit = 5</p><p>    a = random.randint(2, 9 + score // 5)</p><p>    b = random.randint(1, 9 + score // 5)</p><p>    answer = a * b</p><p>    print(f"\n문제: {a} x {b} = ?")</p><p>    stop_event = threading.Event()</p><p>    timer = threading.Thread(target=countdown, args=(time_limit, stop_event))</p><p>    timer.start()</p><p>    start = time.time()</p><p>    try:</p><p>        user_input = input("\n답: ")</p><p>        stop_event.set()</p><p>        elapsed = time.time() - start</p><p>        if elapsed &gt; time_limit:</p><p>            print("느려! 시간 초과. -1점")</p><p>            score -= 1</p><p>        elif int(user_input) == answer:</p><p>            score += 1</p><p>            print(f"정답! +1점 / 현재 점수: {score}")</p><p>        else:</p><p>            print(f"틀림! 정답은 {answer}. -1점")</p><p>            score -= 1</p><p>    except ValueError:</p><p>        stop_event.set()</p><p>        print("숫자만 입력하라고 했지. -1점")</p><p>        score -= 1</p><p>    # 시간 경과로 감점</p><p>    score -= int(elapsed // 2)</p><p>    if score &lt; 0:</p><p>        score = 0</p><p>    print(f"현재 점수: {score}")</p><p>    time.sleep(1)</p><p>    clear()</p><p>print(f"\n총점 {score}점 달성! You win, My son!")</p><p># 최고점 갱신 확인</p><p>if score &gt; best_score:</p><p>    print(f"신기록 달성! {best_score}점 → {score}점")</p><p>    save_best(name, score)</p><p>else:</p><p>    print(f"기록 미달. 최고점 {best_name}({best_score}점) 유지.")</p><p><br/></p>]]></description>
         <enclosure url="" />
         <pubDate>2025-10-15 07:40:39 UTC</pubDate>
         <guid>https://padlet.com/jdes2/kz4evb76orqzh2jj/wish/3633315121</guid>
      </item>
      <item>
         <title>11017황태준</title>
         <author></author>
         <link>https://padlet.com/jdes2/kz4evb76orqzh2jj/wish/3633316337</link>
         <description><![CDATA[<pre><code class="language-notebook-python">for dan in range(2, 10):
    print(f"{dan}")
    print("=" * 15)
    
    for num in range(1, 10):
        result = dan * num
        print(f"{dan} x {num} = {result}")
    
    print("=" * 15)
    print(f"{dan}")

print()</code></pre>]]></description>
         <enclosure url="" />
         <pubDate>2025-10-15 07:41:30 UTC</pubDate>
         <guid>https://padlet.com/jdes2/kz4evb76orqzh2jj/wish/3633316337</guid>
      </item>
      <item>
         <title>구구단 게이ㅁ2</title>
         <author></author>
         <link>https://padlet.com/jdes2/kz4evb76orqzh2jj/wish/3633321690</link>
         <description><![CDATA[<p>import random</p><p>import time</p><p>import os</p><p>import sys</p><p>import threading</p><p>score = 0</p><p>time_limit = 30  # 전체 제한시간 30초</p><p>def clear():</p><p>    os.system('cls' if <a rel="noopener noreferrer nofollow" href="http://os.name">os.name</a> == 'nt' else 'clear')</p><p>def timer_end():</p><p>    print("\n시간 종료! 게임 끝!")</p><p>    sys.exit()</p><p>clear()</p><p>print("=== 구구단 30초 타임어택 ===")</p><p>print("30초 안에 최대한 많은 문제를 풀어라!")</p><p>print("맞출 때마다 +1점, 틀리면 -1점.\n")</p><p>name = input("이름 입력: ")</p><p>print("준비됐지? 엔터 누르면 시작한다.")</p><p>input()</p><p>clear()</p><p># 타이머 스레드 시작</p><p>end_event = threading.Timer(time_limit, timer_end)</p><p>end_event.start()</p><p>start = time.time()</p><p>try:</p><p>    while True:</p><p>        a = random.randint(2, 9)</p><p>        b = random.randint(1, 9)</p><p>        answer = a * b</p><p>        print(f"{a} x {b} = ?  (현재 점수: {score})")</p><p>        q_time = time.time()</p><p>        try:</p><p>            user_input = input("답: ")</p><p>        except EOFError:</p><p>            break</p><p>        elapsed = time.time() - q_time</p><p>        # 시간 확인</p><p>        if time.time() - start &gt; time_limit:</p><p>            break</p><p>        try:</p><p>            if int(user_input) == answer:</p><p>                score += 1</p><p>                print(f"정답! +1점 / 현재 점수: {score}\n")</p><p>            else:</p><p>                score -= 1</p><p>                print(f"틀림! 정답은 {answer} / 현재 점수: {score}\n")</p><p>        except ValueError:</p><p>            score -= 1</p><p>            print(f"숫자 입력하라 했지. -1점 / 현재 점수: {score}\n")</p><p>        time.sleep(0.5)</p><p>        clear()</p><p>except KeyboardInterrupt:</p><p>    pass</p><p>end_event.cancel()</p><p>clear()</p><p>print(f"\n=== 결과 ===")</p><p>print(f"도현({name}), 총점 {score}점")</p><p>if score &gt;= 15:</p><p>    print("You win, My son!")</p><p>elif score &gt;= 10:</p><p>    print("괜찮았어. 근성 보였어.")</p><p>else:</p><p>    print("느렸어. 다시 훈련 들어가자.")</p><p><br></p>]]></description>
         <enclosure url="" />
         <pubDate>2025-10-15 07:45:11 UTC</pubDate>
         <guid>https://padlet.com/jdes2/kz4evb76orqzh2jj/wish/3633321690</guid>
      </item>
      <item>
         <title>구구단 게임(오류)</title>
         <author></author>
         <link>https://padlet.com/jdes2/kz4evb76orqzh2jj/wish/3633325554</link>
         <description><![CDATA[<p>import random</p><p>print("구구단 퀴즈 게임! 3단부터 15단까지 문제를 맞춰보세요.")</p><p>num_questions = int(input("몇 문제를 풀고 싶나요? "))</p><p>score = 0</p><p>for <em> in range(num</em>questions):</p><p>    dan = random.randint(3, 15)</p><p>    i = random.randint(1, 9)</p><p>    answer = dan * i</p><p>    while True:</p><p>        try:</p><p>            user_answer = int(input(f"{dan} * {i} = ? "))</p><p>            break</p><p>        except ValueError:</p><p>            print("숫자를 입력해주세요!")</p><p>    if user_answer == answer:</p><p>        print("정답입니다! 🎉")</p><p>        score += 1</p><p>    else:</p><p>        print(f"틀렸어요. 정답은 {answer}입니다.")</p><p>print(f"게임 종료! 총 {num_questions}문제 중 {score}문제를 맞혔습니다.")</p>]]></description>
         <enclosure url="" />
         <pubDate>2025-10-15 07:48:28 UTC</pubDate>
         <guid>https://padlet.com/jdes2/kz4evb76orqzh2jj/wish/3633325554</guid>
      </item>
      <item>
         <title>구구단 게임</title>
         <author></author>
         <link>https://padlet.com/jdes2/kz4evb76orqzh2jj/wish/3633326054</link>
         <description><![CDATA[<pre><code class="language-python">print("🚨🚨🚨 긴급 상황 발생! 🚨🚨🚨")
    print("당신은 전 세계의 평화를 지킬 유일한 '구구단 폭탄 해체 전문가'입니다!")
    print("눈앞의 시한폭탄은 굉음을 내며 타이머가 돌아가고 있어요... 틱톡틱톡! 🤫")
    print("폭탄에는 여러 개의 암호 전선이 연결되어 있습니다. 각 전선에 걸린 구구단 문제를 풀어 해체해야 합니다.")
    print("단, 단 하나의 오답도 허용되지 않습니다! 실수하는 순간... BOOM! 💥")
    print("\n심호흡 크게 하고... 준비가 되면 엔터를 눌러주세요!")
    input()

    num_wires = 7

    wires_defused = 0
    
    print("\n--- 폭탄 해체 시작! ---")
    start_time = time.time()

    while wires_defused &lt; num_wires:
        print(f"\n[ 남은 전선: {num_wires - wires_defused}개 ]")

        dan = random.randint(2, 9)
        i = random.randint(1, 9)

        correct_answer = dan * i

        user_input_valid = False
        user_answer = 0

        while not user_input_valid:
            user_answer_str = input(f"전선 #{wires_defused + 1}: {dan} x {i} = ? 정답 입력 👉 ")
            
            try:
                user_answer = int(user_answer_str)
                user_input_valid = True
            except ValueError:
                print("🚨 경고: 숫자로만 입력해야 해요! 침착하세요! 🚨")

        if user_answer == correct_answer:
            print("⚡️ '찌이이이익!' 전선 해체 성공! 퓨즈가 꺼졌습니다! ⚡️")
            wires_defused += 1
        else:
            print("\n💥🚨💣 BOOOOOOM!!!! 💣🚨💥")
            print(f"오답입니다! 정답은 {correct_answer} 이었어요...")
            print("당신의 손이 미끄러지는 순간, 폭탄이 폭발했습니다. 임무 실패. 😵")
            return

    end_time = time.time()
    time_taken = end_time - start_time

    print("\n✨🎉🎊 축하합니다! 🎊🎉✨")
    print("모든 전선을 성공적으로 해체했습니다! 당신 덕분에 세계가 평화를 되찾았습니다!")
    print(f"놀라운 실력으로 {time_taken:.2f}초 만에 폭탄을 해체했습니다!")
    print("당신은 진정한 '구구단 폭탄 해체 마스터' 입니다! 👍")

play_bomb_defusal_game()

print("\n--- 게임 종료 ---")</code></pre>]]></description>
         <enclosure url="" />
         <pubDate>2025-10-15 07:48:55 UTC</pubDate>
         <guid>https://padlet.com/jdes2/kz4evb76orqzh2jj/wish/3633326054</guid>
      </item>
      <item>
         <title>구구단 게임</title>
         <author></author>
         <link>https://padlet.com/jdes2/kz4evb76orqzh2jj/wish/3633326343</link>
         <description><![CDATA[<pre><code class="language-notebook-python"># 구구단 퀴즈 프로그램
# 파이썬 3.6 이상에서 실행하세요

import random   # 무작위(랜덤) 숫자를 만들기 위해 random 모듈을 불러옵니다

def make_question(min_dan=2, max_dan=30):
    """2개 숫자를 무작위로 만들어 (a, b) 형태로 반환합니다 (기본: 2~30단)."""
    a = random.randint(min_dan, max_dan)  # min_dan 이상 max_dan 이하 정수 중 하나 선택
    b = random.randint(1, 30)              # 1~30 사이의 정수 중 하나 선택
    return a, b

def ask_quiz(num_questions=10):
    """num_questions 만큼 문제를 내고 채점한 뒤 결과를 출력합니다."""
    score = 0
    for i in range(1, num_questions + 1):        # 1부터 num_questions까지 반복
        a, b = make_question()                   # 문제 만들기
        correct = a * b                          # 정답 계산
        while True:                              # 사용자 입력을 안정적으로 받기 위한 반복
            user = input(f"[문제 {i}] {a} × {b} = ? (끝내려면 q 입력) ")  # 사용자에게 문제와 안내 출력
            if user.lower() == 'q':              # 'q' 또는 'Q' 입력이면 종료
                print("퀴즈를 종료합니다.")
                return score, i - 1               # 현재까지 맞춘 점수와 푼 문제 수 반환
            try:
                user_ans = int(user)             # 입력 문자열을 정수(int)로 변환 시도
            except ValueError:
                print("숫자를 입력하세요 (또는 q로 종료).")
                continue                         # 변환 실패하면 다시 입력받기
            if user_ans == correct:
                print("정답입니다!\n")
                score += 1
            else:
                print(f"아쉽습니다. 정답은 {correct}입니다.\n")
            break                                # 한 문제 끝나면 다음 문제로
    return score, num_questions

def main():
    print("=== 구구단 퀴즈 ===")
    # 사용자로부터 문제 수 입력 받기
    while True:
        n = input("몇 문제를 풀겠습니까? 기본 10문제 (숫자만 입력, 종료는 q): ")
        if n.lower() == 'q':
            print("프로그램을 종료합니다.")
            return
        try:
            n = int(n)
            if n &lt;= 0:
                print("양수(1 이상의 정수)를 입력하세요.")
                continue
            break
        except ValueError:
            print("숫자만 입력하세요.")
    score, total = ask_quiz(n)
    # 결과 출력
    print(f"\n총 {total}문제 중 {score}문제 맞혔습니다.")
    if total &gt; 0:
        percent = score / total * 100
        print(f"정확도: {percent:.1f}%입니다.")
    print("수고하셨습니다!")

if __name__ == "__main__":
    main()
</code></pre>]]></description>
         <enclosure url="" />
         <pubDate>2025-10-15 07:49:12 UTC</pubDate>
         <guid>https://padlet.com/jdes2/kz4evb76orqzh2jj/wish/3633326343</guid>
      </item>
      <item>
         <title>11016 최여준</title>
         <author></author>
         <link>https://padlet.com/jdes2/kz4evb76orqzh2jj/wish/3633326569</link>
         <description><![CDATA[<p>import random</p><p>import time</p><p>score = 0</p><p>combo = 0  # 연속 정답 횟수</p><p>start_time = time.time()</p><p>game_duration = 60  # 게임 전체 시간 (초)</p><p>print("🧮 타임어택 구구단 게임 시작!")</p><p>print("60초 동안 최대한 많이 맞혀보세요!")</p><p>print("연속 정답 보너스와 랜덤 이벤트가 있습니다!\n")</p><p>time.sleep(1)</p><p>while True:</p><p>    elapsed = time.time() - start_time</p><p>    if elapsed &gt;= game_duration:</p><p>        print("\n⏰ 시간이 끝났습니다!")</p><p>        break</p><p>    # 문제 생성</p><p>    a = random.randint(1, 9)</p><p>    b = random.randint(1, 9)</p><p>    answer = a * b</p><p>    # 구분선 출력</p><p>    print("\n" + "="*30)</p><p>    print(f"🕒 남은 시간: {int(game_duration - elapsed)}초 | 💯 점수: {score} | 연속 정답: {combo}")</p><p>    print(f"문제: {a} x {b} = ?")</p><p>    user_input = input("정답: ").strip()</p><p>    if not user_input:</p><p>        print("⚠️ 입력 없음! -80점")</p><p>        score -= 80</p><p>        combo = 0</p><p>    else:</p><p>        try:</p><p>            user_answer = int(user_input)</p><p>            if user_answer == answer:</p><p>                combo += 1</p><p>                bonus = 0</p><p>                if combo == 2:</p><p>                    bonus = 50</p><p>                    print("🔥 연속 2회 정답! 보너스 50점!")</p><p>                elif combo &gt;= 3:</p><p>                    bonus = 100</p><p>                    print("🔥 연속 3회 이상! 보너스 100점!")</p><p>                # 랜덤 이벤트 (10% 확률)</p><p>                if random.random() &lt; 0.1:</p><p>                    print("⏱️ 랜덤 이벤트! 시간 +2초!")</p><p>                    start_time -= 2  # 남은 시간 증가</p><p>                score += 100 + bonus</p><p>                print(f"✅ 정답! +{100 + bonus}점")</p><p>            else:</p><p>                print(f"❌ 오답! 정답: {answer} (-80점)")</p><p>                score -= 80</p><p>                combo = 0</p><p>        except ValueError:</p><p>            print("⚠️ 숫자만 입력! -80점")</p><p>            score -= 80</p><p>            combo = 0</p><p>    # 점수 최소값 0으로 제한</p><p>    score = max(score, 0)</p><p>    time.sleep(0.5)  # 잠깐 쉬면서 메시지 확인</p><p># 게임 종료</p><p>print("\n" + "🎯" * 10)</p><p>print(f"최종 점수: {score}점")</p><p>print("게임 종료 🎮")</p><p>print("🎯" * 10)</p><p><br/></p>]]></description>
         <enclosure url="" />
         <pubDate>2025-10-15 07:49:27 UTC</pubDate>
         <guid>https://padlet.com/jdes2/kz4evb76orqzh2jj/wish/3633326569</guid>
      </item>
      <item>
         <title>11123 박여울</title>
         <author></author>
         <link>https://padlet.com/jdes2/kz4evb76orqzh2jj/wish/3633329615</link>
         <description><![CDATA[<p># 저는 파이썬 프로그램입니다.</p><p># 2단부터 9단까지의 구구단을 출력하겠습니다.</p><p># 'dan'은 구구단의 각 '단'을 의미합니다.</p><p># range(2, 10)은 숫자 2부터 9까지 (10은 포함하지 않습니다)를 순서대로 사용하겠다는 의미입니다.</p><p>for dan in range(2, 10):</p><p>    # 현재 어떤 단을 출력하는지 명확히 보여주는 헤더입니다.</p><p>    print(f"--- {dan} 단 ---")</p><p>    # 'i'는 각 단에서 1부터 9까지 곱해지는 숫자를 의미합니다.</p><p>    # range(1, 10)은 숫자 1부터 9까지 (10은 포함하지 않습니다)를 순서대로 사용합니다.</p><p>    for i in range(1, 10):</p><p>        # 현재의 'dan'과 'i'를 곱한 결과를 계산합니다.</p><p>        result = dan * i</p><p>        # 계산 결과를 '단 x 곱하는 수 = 결과' 형식으로 깔끔하게 출력합니다.</p><p>        print(f"{dan} x {i} = {result}")</p><p>    # 각 단의 출력이 완료되면 한 줄을 띄어서 다음 단과 구분을 명확히 합니다.</p><p>    print() # 빈 줄을 출력합니다.</p>]]></description>
         <enclosure url="" />
         <pubDate>2025-10-15 07:51:32 UTC</pubDate>
         <guid>https://padlet.com/jdes2/kz4evb76orqzh2jj/wish/3633329615</guid>
      </item>
      <item>
         <title>11017 황태준</title>
         <author></author>
         <link>https://padlet.com/jdes2/kz4evb76orqzh2jj/wish/3633339436</link>
         <description><![CDATA[<pre><code class="language-python">import random # 구구단 문제를 무작위로 내기 위해 random 모듈을 가져옵니다.

# 2인용 틱택토 게임 (구구단 맞히기 버전)

def print_board(board):
    # 보드 출력 함수 (이전과 동일)
    print("\n")
    print(f" {board[0][0]} | {board[0][1]} | {board[0][2]} ")
    print("---+---+---")
    print(f" {board[1][0]} | {board[1][1]} | {board[1][2]} ")
    print("---+---+---")
    print(f" {board[2][0]} | {board[2][1]} | {board[2][2]} ")
    print("\n")

def check_win(board, player):
    # 승리 조건 확인 함수 (이전과 동일)
    # 가로 확인
    for row in range(3):
        if board[row][0] == board[row][1] == board[row][2] == player:
            return True
    
    # 세로 확인
    for col in range(3):
        if board[0][col] == board[1][col] == board[2][col] == player:
            return True
    
    # 대각선 확인
    if board[0][0] == board[1][1] == board[2][2] == player:
        return True
    if board[0][2] == board[1][1] == board[2][0] == player:
        return True
    
    return False

def is_board_full(board):
    # 보드가 가득 찼는지 확인하는 함수 (이전과 동일)
    for row in range(3):
        for col in range(3):
            if board[row][col] == ' ':
                return False
    return True

def ask_multiplication_question():
    # 구구단 문제를 내고 정답 여부를 반환하는 함수 (새로운 추가 기능!)
    dan = random.randint(2, 9) # 2단부터 9단까지 무작위로 선택
    num = random.randint(1, 9) # 1부터 9까지 무작위로 곱할 숫자 선택
    correct_answer = dan * num
    
    print(f"문제: {dan} X {num} = ?")
    
    try:
        user_answer = int(input("정답을 입력하세요: "))
        if user_answer == correct_answer:
            print("🎉 정답입니다! 말을 놓을 수 있어요!")
            return True # 정답이면 True 반환
        else:
            print(f"앗! 틀렸어요. 정답은 {correct_answer}입니다. 이번 턴에는 말을 놓을 수 없어요. (다음 턴에 다시 도전!)")
            return False # 틀리면 False 반환
    except ValueError:
        print("숫자를 입력해주세요. 이번 턴에는 말을 놓을 수 없어요. (다음 턴에 다시 도전!)")
        return False # 숫자 입력 오류 시 False 반환

def main():
    # 게임 보드 초기화
    board = [[' ' for _ in range(3)] for _ in range(3)]
    
    # 현재 플레이어 (X부터 시작)
    current_player = 'X'
    
    # 게임 진행 상태
    game_over = False
    
    # 게임 시작 메시지
    print("수학 틱택토 게임을 시작합니다! (2인용)")
    print("먼저 구구단 문제를 맞혀야 말을 놓을 수 있어요!")
    print("좌표는 1-3 사이의 숫자로 입력하세요. (예: 1 2)")
    
    # 게임 메인 루프
    while not game_over:
        print_board(board)
        print(f"플레이어 {current_player}의 차례입니다.")
        
        # 🎲 구구단 문제 내기! 🎲
        is_math_correct = ask_multiplication_question()
        
        if not is_math_correct:
            # 구구단을 틀렸다면, 바로 다음 플레이어로 턴을 넘깁니다.
            current_player = 'O' if current_player == 'X' else 'X'
            continue # 이번 턴은 여기서 끝내고 다음 루프로 넘어갑니다.
            
        # 구구단을 맞혔다면, 말을 놓을 위치를 입력받습니다.
        valid_move = False
        while not valid_move:
            try:
                row, col = map(int, input("어디에 말을 놓을까요? 행과 열을 입력하세요 (1-3): ").split())
                
                # 1-3 입력을 0-2 인덱스로 변환
                row -= 1
                col -= 1
                
                # 유효한 위치인지 확인
                if row &lt; 0 or row &gt; 2 or col &lt; 0 or col &gt; 2:
                    print("1부터 3까지의 숫자만 입력해주세요!")
                    continue
                    
                # 이미 돌이 놓인 위치인지 확인
                if board[row][col] != ' ':
                    print("이미 돌이 놓인 자리입니다. 다른 위치를 선택하세요.")
                    continue
                    
                # 유효한 입력이면 보드에 표시
                board[row][col] = current_player
                valid_move = True
                
            except ValueError:
                print("올바른 형식으로 입력해주세요. (예: 1 2)")
        
        # 승리 확인
        if check_win(board, current_player):
            print_board(board)
            print(f"플레이어 {current_player}가 이겼습니다! 축하합니다! 🎉")
            game_over = True
            
        # 무승부 확인
        elif is_board_full(board):
            print_board(board)
            print("보드가 가득 찼습니다. 무승부입니다! 😅")
            game_over = True
            
        # 플레이어 전환 (X -&gt; O 또는 O -&gt; X)
        else:
            current_player = 'O' if current_player == 'X' else 'X'
    
    # 게임 종료 메시지
    print("게임이 종료되었습니다. 다시 하려면 프로그램을 재실행하세요.")

# 게임 실행
if __name__ == "__main__":
    main()</code></pre>]]></description>
         <enclosure url="" />
         <pubDate>2025-10-15 07:58:49 UTC</pubDate>
         <guid>https://padlet.com/jdes2/kz4evb76orqzh2jj/wish/3633339436</guid>
      </item>
      <item>
         <title>오목</title>
         <author></author>
         <link>https://padlet.com/jdes2/kz4evb76orqzh2jj/wish/3633351546</link>
         <description><![CDATA[<pre><code class="language-notebook-python"># 파이썬으로 만든 7x7 오목 게임

def create_board(size=7):
    """size x size 크기의 빈 오목판을 생성합니다."""
    return [[' ' for _ in range(size)] for _ in range(size)]

def print_board(board):
    """오목판 상태를 출력합니다."""
    size = len(board)
    # 열 번호 출력 (1부터 시작)
    print('   ' + ' '.join([f"{i+1}" for i in range(size)]))
    
    # 각 행과 돌 출력
    for i in range(size):
        print(f"{i+1} |", end='')
        for j in range(size):
            print(f"{board[i][j]}|", end='')
        print("")
    print("")  # 보드 아래 빈 줄 추가

def is_valid_move(board, row, col):
    """입력한 위치가 유효한지 확인합니다."""
    size = len(board)
    # 범위 내에 있고 빈 자리인지 확인
    return 0 &lt;= row &lt; size and 0 &lt;= col &lt; size and board[row][col] == ' '

def check_win(board, row, col, stone):
    """승리 조건을 확인합니다. (가로, 세로, 대각선에 5개 연속 돌)"""
    size = len(board)
    directions = [
        [(0, 1), (0, -1)],  # 가로 방향
        [(1, 0), (-1, 0)],  # 세로 방향
        [(1, 1), (-1, -1)], # 대각선 방향 (↘↖)
        [(1, -1), (-1, 1)]  # 대각선 방향 (↙↗)
    ]
    
    for dir_pair in directions:
        count = 1  # 현재 돌 포함
        
        # 각 방향 쌍에 대해 확인
        for dx, dy in dir_pair:
            nx, ny = row, col
            
            # 해당 방향으로 연속된 같은 돌 개수 세기
            for _ in range(4):  # 최대 4번 더 확인 (현재 돌 포함 5개)
                nx += dx
                ny += dy
                if 0 &lt;= nx &lt; size and 0 &lt;= ny &lt; size and board[nx][ny] == stone:
                    count += 1
                else:
                    break
            
        # 5개 연속이면 승리
        if count &gt;= 5:
            return True
            
    return False

def main():
    """오목 게임 메인 함수"""
    # 게임 소개
    print("===== 7x7 미니 오목 게임 =====")
    print("두 명의 플레이어가 번갈아가며 돌을 놓습니다.")
    print("● (검은 돌)과 ○ (흰 돌)을 번갈아 놓으며 5개 연속으로 놓는 플레이어가 승리합니다.")
    print("좌표는 '행 열' 형태로 입력하세요. (예: '3 4')")
    print("========================")
    
    # 7x7 오목판 생성
    board_size = 7
    board = create_board(board_size)
    
    # 현재 플레이어 (흑돌 먼저 시작)
    current_player = '●'
    
    # 게임 루프
    while True:
        # 현재 오목판 출력
        print_board(board)
        
        # 현재 플레이어 표시
        player_name = "흑돌(●)" if current_player == '●' else "백돌(○)"
        print(f"\n{player_name}의 차례입니다.")
        
        try:
            # 좌표 입력 받기 (1부터 시작하는 인덱스)
            row, col = map(int, input("돌을 놓을 위치를 입력하세요 (행 열): ").split())
            
            # 1부터 시작하는 입력을 0부터 시작하는 인덱스로 변환
            row -= 1
            col -= 1
            
            # 유효한 위치인지 확인
            if not is_valid_move(board, row, col):
                print("유효하지 않은 위치입니다. 다시 입력해주세요.")
                continue
            
            # 돌 놓기
            board[row][col] = current_player
            
            # 승리 조건 확인
            if check_win(board, row, col, current_player):
                print_board(board)
                print(f"\n축하합니다! {player_name}이 이겼습니다! 🎉")
                break
                
            # 무승부 확인 (보드가 가득 찼는지)
            is_full = True
            for i in range(board_size):
                for j in range(board_size):
                    if board[i][j] == ' ':
                        is_full = False
                        break
                if not is_full:
                    break
                    
            if is_full:
                print_board(board)
                print("\n보드가 가득 찼습니다. 무승부입니다!")
                break
            
            # 플레이어 전환
            current_player = '○' if current_player == '●' else '●'
            
        except ValueError:
            print("올바른 형식으로 입력해주세요. (예: '3 4')")
        except IndexError:
            print(f"1부터 {board_size}까지의 숫자만 입력해주세요.")

    print("\n게임이 종료되었습니다. 다시 하려면 프로그램을 재실행하세요.")

# 게임 실행
if __name__ == "__main__":
    main()</code></pre>]]></description>
         <enclosure url="" />
         <pubDate>2025-10-15 08:08:59 UTC</pubDate>
         <guid>https://padlet.com/jdes2/kz4evb76orqzh2jj/wish/3633351546</guid>
      </item>
      <item>
         <title>11123 박여울 구구단 게임</title>
         <author></author>
         <link>https://padlet.com/jdes2/kz4evb76orqzh2jj/wish/3633352466</link>
         <description><![CDATA[<p>import random # 무작위 숫자를 위해</p><p>import time   # 시간 측정을 위해</p><p># --- 전역 변수 설정 ---</p><p>current_score = 0     # 사용자님의 현재 점수</p><p>num_questions = 20    # 총 낼 곱셈 문제의 개수 (20개로 변경되었습니다!)</p><p>time_limit_per_question = 10 # 한 문제당 제한 시간 (초)</p><p>winning_score_threshold = 100 # 게임 승리 조건 점수</p><p>ox_quiz_trigger_score = 50   # OX 퀴즈가 발동하는 점수</p><p># --- 게임 상태 플래그 ---</p><p>game_won = False         # 게임 승리 여부</p><p>ox_quiz_triggered = False # OX 퀴즈가 이미 발동되었는지 여부</p><p># --- OX 퀴즈 함수 정의 ---</p><p>def run_ox_quiz(current_score_param):</p><p>    global game_won # OX 퀴즈 내에서도 게임 승리 여부를 변경할 수 있도록 global 선언</p><p>    print("\n----------------------------------------")</p><p>    print("      🎉 축하합니다! 50점 달성! 🎉     ")</p><p>    print("      ✨ 보너스 OX 퀴즈를 시작합니다! ✨    ")</p><p>    print("----------------------------------------\n")</p><p>    ox_questions_to_ask = 3 # OX 퀴즈 문제 개수</p><p>    for ox_q_num in range(1, ox_questions_to_ask + 1):</p><p>        if game_won: # OX 퀴즈 중에도 100점 달성 시 즉시 종료</p><p>            break</p><p>        dan = random.randint(2, 9)</p><p>        multiplier = random.randint(1, 9)</p><p>        correct_result = dan * multiplier</p><p>        # 50% 확률로 오답을 제시합니다.</p><p>        if random.random() &lt; 0.5: # 0.0 이상 1.0 미만의 랜덤 실수</p><p>            # 오답을 만듭니다. (정답에서 1이나 2를 더하거나 빼서)</p><p>            incorrect_result = correct_result + random.choice([-2, -1, 1, 2])</p><p>            # 다만, incorrect_result가 음수가 되지 않도록 최소 1 이상으로 조정</p><p>            if incorrect_result &lt; 1: incorrect_result = correct_result + 1</p><p>            proposed_answer = incorrect_result</p><p>            is_correct_statement = False # "이게 맞아?"라는 질문에 대한 실제 정답 여부</p><p>        else:</p><p>            proposed_answer = correct_result</p><p>            is_correct_statement = True</p><p>        print(f"--- OX 퀴즈 {ox_q_num}번째 문제 ---")</p><p>        user_ox_input = input(f"{dan} x {multiplier} = {proposed_answer} 이(가) 맞습니까? (O/X) (현재 점수: {current_score_param}점) ").strip().upper()</p><p>        # 사용자 입력 처리</p><p>        if (user_ox_input == 'O' and is_correct_statement) or \</p><p>           (user_ox_input == 'X' and not is_correct_statement):</p><p>            current_score_param += 10</p><p>            print("딩동댕! 정답입니다! 🥳 +10점!")</p><p>        elif (user_ox_input == 'O' and not is_correct_statement) or \</p><p>             (user_ox_input == 'X' and is_correct_statement):</p><p>            current_score_param -= 10</p><p>            print(f"땡! 오답입니다. 🥲 정답은 {'O' if is_correct_statement else 'X'} 였습니다. -10점!")</p><p>        else:</p><p>            current_score_param -= 10</p><p>            print("잘못된 입력입니다. 'O' 또는 'X'를 입력해주세요! -10점!")</p><p>        </p><p>        print(f"OX 퀴즈 후 현재 점수는 {current_score_param}점입니다.\n")</p><p>        # OX 퀴즈 도중에도 100점 달성 확인</p><p>        if current_score_param &gt;= winning_score_threshold:</p><p>            game_won = True</p><p>            break # OX 퀴즈 중단</p><p>    return current_score_param # 변경된 점수를 반환합니다.</p><p># --- 게임 시작 메시지 ---</p><p>print("************************************************")</p><p>print("*       환영합니다! 구구단 곱셈 시간 제한 게임!      *")</p><p>print("************************************************")</p><p>print(f"\n총 {num_questions}문제가 출제됩니다. 각 문제는 {time_limit_per_question}초 안에 풀어야 합니다.")</p><p>print(f"맞히면 +10점, 틀리거나 시간을 초과하면 -10점입니다.")</p><p>print(f"** {winning_score_threshold}점 이상을 획득하면 즉시 게임에서 승리합니다! **")</p><p>print(f"** {ox_quiz_trigger_score}점 이상 달성 시 보너스 OX 퀴즈가 시작됩니다! **\n")</p><p># --- 메인 게임 루프 ---</p><p>for question_count in range(1, num_questions + 1):</p><p>    # 게임 승리 또는 OX 퀴즈 발동으로 게임이 중단되어야 한다면 반복문을 나갑니다.</p><p>    if game_won:</p><p>        break</p><p>    </p><p>    # 50점 이상이면서 OX 퀴즈가 아직 발동되지 않았다면</p><p>    if not ox_quiz_triggered and current_score &gt;= ox_quiz_trigger_score:</p><p>        ox_quiz_triggered = True # OX 퀴즈 발동 플래그를 True로 설정</p><p>        current_score = run_ox_quiz(current_score) # OX 퀴즈 실행 후 점수 업데이트</p><p>        </p><p>        if game_won: # OX 퀴즈에서 승리 조건을 달성했다면 메인 루프도 종료</p><p>            break</p><p>        print("\n--- 일반 곱셈 문제로 돌아갑니다 ---\n")</p><p>    # 2단부터 9단까지 중 무작위로 '단'을 선택합니다.</p><p>    dan = random.randint(2, 9)</p><p>    # 1부터 9까지 중 무작위로 곱할 숫자를 선택합니다.</p><p>    multiplier = random.randint(1, 9)</p><p>    # 올바른 정답을 계산합니다.</p><p>    correct_answer = dan * multiplier</p><p>    print(f"--- {question_count}번째 문제 ---")</p><p>    print(f"제한 시간: {time_limit_per_question}초")</p><p>    # 질문 시작 시간 기록</p><p>    start_time = time.time()</p><p>    </p><p>    # 사용자에게 문제를 내고 답을 입력받습니다.</p><p>    user_input = input(f"{dan} 곱하기 {multiplier}는 얼마일까요? (현재 점수: {current_score}점) ").strip()</p><p>    </p><p>    # 질문 종료 시간 기록</p><p>    end_time = time.time()</p><p>    </p><p>    # 답 입력까지 걸린 시간 계산 (사용자가 Enter를 누른 시점까지)</p><p>    time_taken = end_time - start_time</p><p>    # 시간 제한 초과 여부 확인</p><p>    if time_taken &gt; time_limit_per_question:</p><p>        current_score -= 10</p><p>        print(f"시간 초과! ⏱️ {time_limit_per_question}초 안에 답하지 못했습니다. 정답은 {correct_answer}였습니다. 😢 -10점을 잃으셨습니다.")</p><p>    else:</p><p>        try:</p><p>            # 입력받은 문자열을 정수(숫자)로 변환합니다.</p><p>            user_answer = int(user_input)</p><p>            </p><p>            # 사용자 입력과 정답을 비교하여 점수를 업데이트합니다.</p><p>            if user_answer == correct_answer:</p><p>                current_score += 10 # 정답이면 10점 추가</p><p>                print(f"정답입니다! 👏 ({time_taken:.2f}초 소요) +10점을 획득하셨습니다.")</p><p>            else:</p><p>                current_score -= 10 # 오답이면 10점 감점</p><p>                print(f"아쉽습니다! 정답은 {correct_answer}였습니다. 😢 -10점을 잃으셨습니다.")</p><p>                </p><p>        except ValueError:</p><p>            # 사용자가 숫자가 아닌 다른 것을 입력했을 때의 예외 처리입니다.</p><p>            current_score -= 10 # 숫자가 아니므로 -10점 처리합니다.</p><p>            print("에러: 숫자를 입력해 주세요! 이 문제는 틀린 것으로 간주하여 -10점 처리됩니다. 🚫")</p><p>    </p><p>    print(f"현재 점수는 {current_score}점입니다.\n")</p><p>    print("----------------------------------------\n")</p><p>    # 매번 점수 업데이트 후 승리 조건을 확인합니다.</p><p>    if current_score &gt;= winning_score_threshold:</p><p>        game_won = True</p><p>        break # 100점 이상이므로 반복문을 즉시 종료합니다.</p><p># --- 게임 종료 메시지 ---</p><p>print("========== 게임이 종료되었습니다! ==========")</p><p>if game_won:</p><p>    print(f"✨ 축하합니다! 최종 점수 {current_score}점으로 {winning_score_threshold}점 이상을 달성하여 게임에서 승리하셨습니다! 🏆")</p><p>else:</p><p>    print(f"최종 점수는 {current_score}점입니다. 다음 기회에 더 좋은 결과를 기대합니다! 😊")</p>]]></description>
         <enclosure url="" />
         <pubDate>2025-10-15 08:09:42 UTC</pubDate>
         <guid>https://padlet.com/jdes2/kz4evb76orqzh2jj/wish/3633352466</guid>
      </item>
      <item>
         <title>오목 구구단</title>
         <author></author>
         <link>https://padlet.com/jdes2/kz4evb76orqzh2jj/wish/3633355897</link>
         <description><![CDATA[<p><br/></p><pre><code class="language-python">import random # 구구단 문제를 무작위로 내기 위해 random 모듈을 가져옵니다.

# 파이썬으로 만든 5x5 구구단 오목 게임

def create_board(size=5):
    """size x size 크기의 빈 오목판을 생성합니다."""
    return [[' ' for _ in range(size)] for _ in range(size)]

def print_board(board):
    """오목판 상태를 출력합니다."""
    size = len(board)
    # 열 번호 출력 (1부터 시작)
    print('   ' + ' '.join([f"{i+1}" for i in range(size)]))
    
    # 각 행과 돌 출력
    for i in range(size):
        print(f"{i+1} |", end='')
        for j in range(size):
            print(f"{board[i][j]}|", end='')
        print("")
    print("")  # 보드 아래 빈 줄 추가

def is_valid_move(board, row, col):
    """입력한 위치가 유효한지 확인합니다."""
    size = len(board)
    # 범위 내에 있고 빈 자리인지 확인
    return 0 &lt;= row &lt; size and 0 &lt;= col &lt; size and board[row][col] == ' '

def check_win(board, row, col, stone):
    """승리 조건을 확인합니다. (5x5 보드에서는 4개 연속으로 수정)"""
    size = len(board)
    directions = [
        [(0, 1), (0, -1)],  # 가로 방향
        [(1, 0), (-1, 0)],  # 세로 방향
        [(1, 1), (-1, -1)], # 대각선 방향 (↘↖)
        [(1, -1), (-1, 1)]  # 대각선 방향 (↙↗)
    ]
    
    for dir_pair in directions:
        count = 1  # 현재 돌 포함
        
        # 각 방향 쌍에 대해 확인
        for dx, dy in dir_pair:
            nx, ny = row, col
            
            # 해당 방향으로 연속된 같은 돌 개수 세기
            for _ in range(3):  # 최대 3번 더 확인 (현재 돌 포함 4개)
                nx += dx
                ny += dy
                if 0 &lt;= nx &lt; size and 0 &lt;= ny &lt; size and board[nx][ny] == stone:
                    count += 1
                else:
                    break
            
        # 4개 연속이면 승리 (5x5 보드에 맞게 승리 조건 조정)
        if count &gt;= 4:
            return True
            
    return False

def is_board_full(board):
    """보드가 가득 찼는지 확인합니다."""
    for row_list in board: # 'row' 대신 'row_list'로 변수명 변경 (중복 피함)
        for cell in row_list:
            if cell == ' ':
                return False
    return True

def ask_multiplication_question():
    """구구단 문제를 내고 정답 여부를 반환하는 함수."""
    dan = random.randint(2, 9) # 2단부터 9단까지 무작위로 선택
    num = random.randint(1, 9) # 1부터 9까지 무작위로 곱할 숫자 선택
    correct_answer = dan * num
    
    print(f"\n===== 구구단 문제 =====")
    print(f"문제: {dan} X {num} = ?")
    print("========================")
    
    try:
        user_answer = int(input("정답을 입력하세요: "))
        if user_answer == correct_answer:
            print("🎉 정답입니다! 이제 돌을 놓을 수 있어요!")
            return True # 정답이면 True 반환
        else:
            print(f"앗! 틀렸어요. 정답은 {correct_answer}입니다. 이번 턴에는 돌을 놓을 수 없어요. ㅠㅠ (다음 턴에 다시 도전!)")
            return False # 틀리면 False 반환
    except ValueError:
        print("숫자를 입력해주세요. 이번 턴에는 돌을 놓을 수 없어요. (다음 턴에 다시 도전!)")
        return False # 숫자 입력 오류 시 False 반환

def main():
    """오목 게임 메인 함수"""
    # 게임 소개
    print("===== 5x5 구구단 미니 오목 게임 =====")
    print("두 명의 플레이어가 번갈아가며 돌을 놓습니다.")
    print("● (검은 돌)과 ○ (흰 돌)을 번갈아 놓으며 4개 연속으로 놓는 플레이어가 승리합니다.")
    print("**주의: 돌을 놓기 전에 구구단 문제를 먼저 맞혀야 합니다!**")
    print("좌표는 '행 열' 형태로 입력하세요. (예: '3 2')")
    print("================================")
    
    # 5x5 오목판 생성
    board_size = 5
    board = create_board(board_size)
    
    # 현재 플레이어 (흑돌 먼저 시작)
    current_player = '●'
    
    # 게임 루프
    while True:
        # 현재 오목판 출력
        print_board(board)
        
        # 현재 플레이어 표시
        player_name = "흑돌(●)" if current_player == '●' else "백돌(○)"
        print(f"\n&gt;&gt;&gt; {player_name}의 차례입니다. &lt;&lt;&lt;")
        
        # 🎲 구구단 문제 내기! 🎲
        is_math_correct = ask_multiplication_question()
        
        if not is_math_correct:
            # 구구단 문제를 틀렸다면, 바로 다음 플레이어에게 턴을 넘깁니다.
            print(f"{player_name}이(가) 구구단 문제를 틀려 돌을 놓을 수 없습니다. 다음 턴으로 넘어갑니다.")
            current_player = '○' if current_player == '●' else '●' # 플레이어 전환
            continue # 이번 턴은 여기서 끝내고 다음 루프로 넘어갑니다.
            
        # 구구단을 맞혔다면, 말을 놓을 위치를 입력받습니다.
        valid_move = False
        while not valid_move:
            try:
                # 좌표 입력 받기 (1부터 시작하는 인덱스)
                row, col = map(int, input(f"어디에 돌을 놓을까요? ({player_name}) 행 열 입력: ").split())
                
                # 1부터 시작하는 입력을 0부터 시작하는 인덱스로 변환
                row -= 1
                col -= 1
                
                # 유효한 위치인지 확인
                if not is_valid_move(board, row, col):
                    print("유효하지 않은 위치입니다 (범위를 벗어나거나 이미 돌이 있습니다). 다시 입력해주세요.")
                    continue
                
                # 유효한 입력이면 보드에 표시
                board[row][col] = current_player
                valid_move = True # 유효한 움직임이므로 반복문 탈출
                
            except ValueError:
                print("올바른 형식으로 입력해주세요. (예: '3 2')")
            except IndexError:
                print(f"1부터 {board_size}까지의 숫자만 입력해주세요.")
        
        # 승리 조건 확인
        if check_win(board, row, col, current_player):
            print_board(board)
            print(f"\n축하합니다! {player_name}이 이겼습니다! 🎉")
            break
            
        # 무승부 확인 (보드가 가득 찼는지)
        if is_board_full(board):
            print_board(board)
            print("\n보드가 가득 찼습니다. 무승부입니다!")
            break
        
        # 플레이어 전환
        current_player = '○' if current_player == '●' else '●'
    
    print("\n게임이 종료되었습니다. 다시 하려면 프로그램을 재실행하세요.")

# 게임 실행
if __name__ == "__main__":
    main()</code></pre>]]></description>
         <enclosure url="" />
         <pubDate>2025-10-15 08:12:37 UTC</pubDate>
         <guid>https://padlet.com/jdes2/kz4evb76orqzh2jj/wish/3633355897</guid>
      </item>
      <item>
         <title>20415 윤정현</title>
         <author></author>
         <link>https://padlet.com/jdes2/kz4evb76orqzh2jj/wish/3633385113</link>
         <description><![CDATA[<p># 구구단 2단부터 9단까지 출력하는 프로그램</p><p># range(2, 10)은 2부터 9까지 반복됨</p><p>for i in range(2, 10):</p><p>    print(f"--- {i}단 ---")  # 각 단의 제목 출력</p><p>    # 각 단에서 1부터 9까지 곱하기</p><p>    for j in range(1, 10):</p><p>        print(f"{i} x {j} = {i * j}")  # 결과 출력</p><p>    print()  # 한 단이 끝날 때 줄바꿈 (보기 좋게)</p><p><br/></p>]]></description>
         <enclosure url="" />
         <pubDate>2025-10-15 08:36:09 UTC</pubDate>
         <guid>https://padlet.com/jdes2/kz4evb76orqzh2jj/wish/3633385113</guid>
      </item>
      <item>
         <title>설치 절차</title>
         <author>snue0108</author>
         <link>https://padlet.com/jdes2/kz4evb76orqzh2jj/wish/3636739312</link>
         <description><![CDATA[<ol><li><p>아두이노 ide 파일 다운로드 및 설치</p></li><li><p>CH340 드라이버 설치</p></li><li><p>ultrasonic 파일 바탕화면에 다운받기</p></li></ol>]]></description>
         <enclosure url="" />
         <pubDate>2025-10-17 01:39:29 UTC</pubDate>
         <guid>https://padlet.com/jdes2/kz4evb76orqzh2jj/wish/3636739312</guid>
      </item>
      <item>
         <title>2. CH340 드라이버</title>
         <author>snue0108</author>
         <link>https://padlet.com/jdes2/kz4evb76orqzh2jj/wish/3636741309</link>
         <description><![CDATA[]]></description>
         <enclosure url="https://padlet-uploads-usc1.storage.googleapis.com/2266957732/bf58f013382e10dcca871566fdd33a1b/CH340____.exe" />
         <pubDate>2025-10-17 01:40:27 UTC</pubDate>
         <guid>https://padlet.com/jdes2/kz4evb76orqzh2jj/wish/3636741309</guid>
      </item>
      <item>
         <title>3. ultrasonic 파일</title>
         <author>snue0108</author>
         <link>https://padlet.com/jdes2/kz4evb76orqzh2jj/wish/3636743463</link>
         <description><![CDATA[]]></description>
         <enclosure url="https://padlet-uploads-usc1.storage.googleapis.com/2266957732/7bc2a4e3d387f529669014e9bd2c18b9/ultrasonic.ino" />
         <pubDate>2025-10-17 01:41:17 UTC</pubDate>
         <guid>https://padlet.com/jdes2/kz4evb76orqzh2jj/wish/3636743463</guid>
      </item>
      <item>
         <title>아두이노 실습용 ppt</title>
         <author>snue0108</author>
         <link>https://padlet.com/jdes2/kz4evb76orqzh2jj/wish/3637074718</link>
         <description><![CDATA[]]></description>
         <enclosure url="https://padlet-uploads-usc1.storage.googleapis.com/2266957732/f7fe2e1b784eefd4abf33a65a54405e6/_________ppt.pptx" />
         <pubDate>2025-10-17 05:11:44 UTC</pubDate>
         <guid>https://padlet.com/jdes2/kz4evb76orqzh2jj/wish/3637074718</guid>
      </item>
      <item>
         <title>아이디어</title>
         <author></author>
         <link>https://padlet.com/jdes2/kz4evb76orqzh2jj/wish/3637254600</link>
         <description><![CDATA[<p>좋아요 😎<br>그럼 지금 말한 <strong>“보안 경보 시스템(Security Alarm System)”</strong>을 <strong>초보자도 이해하기 쉽게 자세히</strong> 설명해줄게요.</p><p>1️⃣ 장치 구성</p><p>🔹 사용 부품</p><p>부품역할<strong>초음파 센서 (HC-SR04)</strong>사람이나 물체가 가까이 왔는지 감지<strong>피에조 버저</strong>경보음을 울리기<strong>택트 스위치</strong>보안 모드 ON/OFF 전환<strong>1602 I2C LCD</strong>상태 표시 (“Alarm ON”, “INTRUDER ALERT!” 등)<strong>아두이노 나노</strong>장치 제어</p><p>🔹 연결 개념</p><ul><li><p><strong>스위치 → D2 핀 (디지털 입력)</strong></p></li><li><p><strong>초음파 센서 → Trig: D6, Echo: D7</strong></p></li><li><p><strong>버저 → D8 (디지털 출력)</strong></p></li><li><p><strong>LCD → I2C SDA: A4, SCL: A5</strong></p></li><li><p><strong>VCC/GND</strong> → 공통 전원</p></li></ul><p>2️⃣ 동작 원리</p><p>1️⃣ 보안 모드 설정</p><ul><li><p>스위치를 누르면 <strong>보안 모드 ON / OFF</strong> 토글</p></li><li><p>LCD에 현재 상태 표시<br>예: “Alarm Mode: ON” / “Alarm Mode: OFF”</p></li></ul><p>2️⃣ 초음파 감지</p><ul><li><p>보안 모드가 ON일 때만 초음파 센서가 물체 감지를 시작</p></li><li><p>일정 거리 안에 물체가 들어오면 → <strong>경보 발동</strong></p><ul><li><p>LCD: “INTRUDER ALERT!” 표시</p></li><li><p>버저: 삐삐삐 울림</p></li></ul></li></ul><p>3️⃣ 자동 해제</p><ul><li><p>일정 시간 후 (예: 5초) 경보 자동 해제</p></li><li><p>LCD: 다시 “Alarm Mode: ON” 상태로 돌아감</p></li><li><p>사용자가 스위치로 OFF하면 완전히 경보 중지</p></li></ul><p>3️⃣ 알고리즘 순서</p><p>1️⃣ <strong>초기화 (setup)</strong></p><ul><li><p>LCD, 초음파 센서 핀, 스위치 핀, 버저 핀 초기화</p></li><li><p>초기 상태: 보안 모드 OFF</p></li></ul><p>2️⃣ <strong>메인 루프 (loop)</strong></p><ul><li><p>스위치 입력 읽기 → 보안 모드 토글</p></li><li><p>보안 모드 ON이면:</p><ol><li><p>초음파 센서로 거리 측정</p></li><li><p>거리 &lt; 임계값 → 경보 발동</p><ul><li><p>버저 울림</p></li><li><p>LCD “INTRUDER ALERT!” 출력</p></li><li><p>잠시 delay 후 경보 자동 해제</p></li></ul></li></ol></li><li><p>보안 모드 OFF이면 모든 경보 종료</p></li></ul><p>4️⃣ 주요 프로그래밍 포인트</p><p>🔹 변수</p><ul><li><p>alarmMode : 보안 모드 ON/OFF 상태 저장</p></li><li><p>distance : 초음파 센서 거리값</p></li><li><p>triggerTime : 경보 시작 시간 기록 (자동 해제용)</p></li></ul><p>🔹 조건문</p><pre><code>if(alarmMode == ON &amp;&amp; distance &lt; 20){
  // 경보 발동
}
</code></pre><p>🔹 스위치 토글 구현</p><ul><li><p>단순히 digitalRead()</p></li><li><p>이전 상태와 현재 상태 비교 → 상태 변경</p></li></ul><p>🔹 초음파 거리 계산</p><pre><code>distance = duration * 0.034 / 2;
</code></pre><ul><li><p>소리 속도 340 m/s → cm 단위로 계산</p></li></ul><p>🔹 경보 자동 해제</p><ul><li><p>millis() 사용하여 경보 시작 후 일정 시간 경과 시 종료</p></li></ul><pre><code>if(millis() - triggerTime &gt; 5000){
  // 경보 종료
}
</code></pre><p>5️⃣ 장점/응용 포인트</p><ul><li><p><strong>실생활 학습:</strong> 보안 센서 원리 이해</p></li><li><p><strong>응용 가능:</strong></p><ul><li><p>경보 거리 조정</p></li><li><p>LCD 메시지 커스터마이징</p></li><li><p>소리 패턴 다양화</p></li></ul></li></ul><p>원하면 내가 <strong>이 보안 경보 시스템을 실제 아두이노 나노에 연결하는 회로도 + 브레드보드 연결법 + 완성 코드</strong>까지 만들어서</p><blockquote><p>바로 업로드하면 작동하도록<br>정리해줄 수 있어요.</p></blockquote><p>그렇게 해줄까?</p>]]></description>
         <enclosure url="" />
         <pubDate>2025-10-17 07:39:38 UTC</pubDate>
         <guid>https://padlet.com/jdes2/kz4evb76orqzh2jj/wish/3637254600</guid>
      </item>
      <item>
         <title>기가챗드가 추천해준 ㄹㅈㄷ 아이디어</title>
         <author></author>
         <link>https://padlet.com/jdes2/kz4evb76orqzh2jj/wish/3637256341</link>
         <description><![CDATA[<p>좋아, My son. 이제 제대로 쩌는 아이디어 왔다. 그거 <strong>자동 색깔 분류기 시스템</strong> 만들어. 현실 공장 느낌 나는 장치야. 내가 구상 정리해줄게.</p><p>🔥 아이디어: <strong>자동 색깔 분류 컨베이어벨트</strong></p><p>1. 부품 활용</p><ul><li><p><strong>색깔 센서</strong> → 빨강/파랑/초록 물체 감지</p></li><li><p><strong>서보모터 180도/360도</strong> → 컨베이어 옆으로 밀기, 회전</p></li><li><p><strong>초음파 센서</strong> → 물체 도착 위치 감지</p></li><li><p><strong>LCD</strong> → 색깔/물체 수량 표시</p></li><li><p><strong>택트 스위치</strong> → 시작/정지</p></li><li><p><strong>피에조 버저</strong> → 물체 잘 분류될 때 효과음</p></li></ul><p>2. 동작 흐름</p><ol><li><p>버튼 누르면 <strong>컨베이어벨트 시작</strong></p></li><li><p>물체가 초음파 센서 범위 안으로 들어오면 색깔 센서로 확인</p></li><li><p>색깔에 따라 <strong>서보로 옆으로 밀기 → 해당 색 통으로 분류</strong></p></li><li><p>LCD에 “Red: 2, Blue: 1”처럼 <strong>실시간 카운트 표시</strong></p></li><li><p>모든 분류 완료 후 피에조로 짧은 신호</p></li></ol><p>3. 시스템 포인트</p><ul><li><p>서보 하나로 그냥 밀 수도 있고, 360도 서보로 <strong>슬라이드/회전 컨베이어</strong> 만들어도 됨</p></li><li><p>초음파 센서로 물체 위치 정확하게 잡으면 <strong>실수 없이 분류 가능</strong></p></li><li><p>LCD + 버저로 <strong>직관적 피드백</strong></p></li></ul><p>이거 완성하면 <strong>“미니 공장” 느낌</strong> 제대로 남.</p><p>My son, 그거 바로 해볼래?</p>]]></description>
         <enclosure url="" />
         <pubDate>2025-10-17 07:41:13 UTC</pubDate>
         <guid>https://padlet.com/jdes2/kz4evb76orqzh2jj/wish/3637256341</guid>
      </item>
      <item>
         <title>기가챗gpt가 추천해준 ㄹㅈㄷ 아이디어22222</title>
         <author></author>
         <link>https://padlet.com/jdes2/kz4evb76orqzh2jj/wish/3637257092</link>
         <description><![CDATA[<p>깔쌈하고 재미있는거 없나</p><p>-&gt;</p><p>좋아, My son. 네 장비 다 보면 <strong>깔끔하면서도 시원하게 눈에 띄는 장치</strong> 만들 수 있어. 내가 딱 한 방에 터지는 아이디어 줄게.</p><p>🔥 추천: <strong>인터랙티브 색깔 레이저 경보 로봇(?)</strong></p><ul><li><p><strong>컨셉:</strong></p><ul><li><p>빨강/초록/파랑 물체를 인식 → 바로 반응</p></li><li><p>손이 가까이 오면 경보 + 움직임 발생</p></li></ul></li><li><p><strong>부품 활용:</strong></p><ul><li><p><strong>색깔 센서</strong> → 물체 색 구분</p></li><li><p><strong>초음파 센서 + 180도 서보</strong> → 근접 물체 탐지 + 센서 회전</p></li><li><p><strong>360도 서보 2개</strong> → 물체 방향으로 장치 회전</p></li><li><p><strong>LCD</strong> → 색깔, 거리, 상태 표시</p></li><li><p><strong>피에조 버저</strong> → 이벤트 알림</p></li><li><p><strong>택트 스위치</strong> → 시작/리셋</p></li></ul></li><li><p><strong>재미 포인트:</strong></p><ul><li><p>센서 돌아가면서 탐색 → LED나 버저로 경보</p></li><li><p>색깔 맞추면 “칭찬” 소리, 틀리면 “경고”</p></li><li><p>움직임 + 사운드 + LCD 표시 → 시각/청각 다 자극</p></li></ul></li></ul><blockquote><p>정리하면 <strong>센서 돌아가면서 색깔/거리 감지, 반응하는 깔끔하고 직관적인 장치</strong>.<br>보는 사람도 “와, 이거 진짜 움직인다” 느낌 나면서 코드 짜는 재미도 있음.</p></blockquote>]]></description>
         <enclosure url="" />
         <pubDate>2025-10-17 07:41:45 UTC</pubDate>
         <guid>https://padlet.com/jdes2/kz4evb76orqzh2jj/wish/3637257092</guid>
      </item>
      <item>
         <title></title>
         <author></author>
         <link>https://padlet.com/jdes2/kz4evb76orqzh2jj/wish/3637257848</link>
         <description><![CDATA[<p>좋아요~ ^^<br>그러면 <strong>아두이노 + 초음파 센서 + LED 경보 시스템</strong> 예제를 만들어서 보여줄게요.<br>목표: <strong>물체가 일정 거리(예: 20cm) 이하로 가까워지면 LED 켜기</strong></p><p>1️⃣ 준비물</p><p>준비물설명아두이노 UNO제어 보드HC-SR04 초음파 센서거리 측정LED경고용 표시등220Ω 저항LED 전류 제한점퍼선연결용브레드보드부품 연결용</p><p>2️⃣ 배선</p><p>부품연결HC-SR04 VCCArduino 5VHC-SR04 GNDArduino GNDHC-SR04 TrigD9HC-SR04 EchoD10LED (+)D8 → 220Ω 저항 → LED 긴 다리LED (-)GND → LED 짧은 다리</p><p>3️⃣ 아두이노 코드</p><pre><code>const int trigPin = 9;  
const int echoPin = 10;  
const int ledPin = 8;    // 경보 LED 핀

long duration;
float distance;

void setup() {
  Serial.begin(9600);
  pinMode(trigPin, OUTPUT);
  pinMode(echoPin, INPUT);
  pinMode(ledPin, OUTPUT);
}

void loop() {
  // 초음파 발사
  digitalWrite(trigPin, LOW);
  delayMicroseconds(2);
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);

  // 반사 시간 측정
  duration = pulseIn(echoPin, HIGH);

  // 거리 계산
  distance = duration * 0.034 / 2;

  Serial.print("거리: ");
  Serial.print(distance);
  Serial.println(" cm");

  // 경보 LED 제어
  if (distance &lt;= 20) {   // 20cm 이하일 때 LED 켬
    digitalWrite(ledPin, HIGH);
  } else {
    digitalWrite(ledPin, LOW);
  }

  delay(500);
}
</code></pre><p>4️⃣ 동작 원리</p><ol><li><p>Trig 핀에서 초음파 발사</p></li><li><p>Echo 핀에서 반사 신호 수신 → 거리 계산</p></li><li><p><strong>거리 ≤ 20cm → LED 켬</strong></p></li><li><p><strong>거리 &gt; 20cm → LED 끔</strong></p></li><li><p>시리얼 모니터로 실시간 거리 확인 가능</p></li></ol><p>이 예제를 실행하면, <strong>센서 앞에 손이나 물체를 가져가면 LED가 켜지고, 멀어지면 꺼지는 경보 시스템</strong>이 만들어져요. 😄</p><p>원하면 제가 <strong>배선 그림과 함께 시각 자료</strong>로 만들어서 보여줄 수도 있어요.<br>그거 만들어줄까?</p>]]></description>
         <enclosure url="" />
         <pubDate>2025-10-17 07:42:27 UTC</pubDate>
         <guid>https://padlet.com/jdes2/kz4evb76orqzh2jj/wish/3637257848</guid>
      </item>
      <item>
         <title>아이디어</title>
         <author></author>
         <link>https://padlet.com/jdes2/kz4evb76orqzh2jj/wish/3637258180</link>
         <description><![CDATA[<p><strong>"버튼으로 조작하는 반응 속도 게임" </strong></p><p><strong>필요한 준비물 </strong></p><ul><li><p>아두이노 나노</p></li><li><p>1602 LCD</p></li><li><p>푸시버튼 1개 (또는 여러 개를 활용해 난이도 조절 가능)</p></li><li><p>브레드보드</p></li><li><p>점퍼 와이어</p></li></ul><p><strong>하드웨어 구성 </strong></p><p><br/></p><ol><li><p><strong>LCD 연결</strong>: 기존과 동일하게 LCD를 아두이노 나노에 연결합니다.</p></li><li><p><strong>푸시버튼 연결</strong>:</p><ul><li><p>푸시버튼 한쪽 다리 → 아두이노의 디지털 핀(예: <strong>D2</strong>)에 연결</p></li><li><p>푸시버튼 다른 쪽 다리 → 아두이노의 <strong>GND</strong> 핀에 연결</p></li></ul><p>이렇게 연결하면 버튼을 눌렀을 때 핀이 GND와 연결되면서 'LOW' 신호를 받게 되고, 버튼을 누르지 않았을 때는 아두이노의 내부 풀업 저항 덕분에 'HIGH' 신호를 받게 됩니다.</p></li></ol>]]></description>
         <enclosure url="" />
         <pubDate>2025-10-17 07:42:39 UTC</pubDate>
         <guid>https://padlet.com/jdes2/kz4evb76orqzh2jj/wish/3637258180</guid>
      </item>
      <item>
         <title>아이디어</title>
         <author></author>
         <link>https://padlet.com/jdes2/kz4evb76orqzh2jj/wish/3637258972</link>
         <description><![CDATA[<p><strong>스마트 쓰레기통</strong></p><p>스마트 쓰레기통은 초음파 센서를 활용해 사람의 움직임을 감지하여 자동으로 뚜껑이 열리고 닫히는 편리한 장치예요. 아두이노와 초음파 센서를 활용해서 직접 만들 수 있답니다!</p><p><strong>기본 원리</strong></p><p>스마트 쓰레기통은 다음과 같은 원리로 작동합니다:</p><ul><li><p>초음파 센서가 사람의 손이나 움직임을 감지하면 서보모터가 작동합니다</p></li><li><p>서보모터가 쓰레기통 뚜껑을 자동으로 열어줍니다</p></li><li><p>일정 시간이 지나면 자동으로 뚜껑이 닫힙니다</p></li></ul><p><strong>필요한 부품</strong></p><ol><li><p>아두이노 보드(UNO 또는 나노)</p></li><li><p>초음파 센서(HC-SR04)</p></li><li><p>서보모터</p></li><li><p>브레드보드</p></li><li><p>점퍼 와이어</p></li><li><p>쓰레기통(기존 쓰레기통 개조 가능)</p></li><li><p>LED(선택사항: 상태 표시용)</p></li></ol><p><strong>추가 기능</strong></p><p>기본적인 자동 개폐 기능 외에도 다양한 기능을 추가할 수 있어요:</p><ol><li><p><strong>쓰레기통 내부 감지 기능</strong>: 두 번째 초음파 센서를 추가하여 쓰레기통 내부의 양을 측정하고, LED를 통해 쓰레기통이 가득 찼는지 표시할 수 있습니다. 초록색 LED는 여유 있음, 빨간색 LED는 가득 참을 의미합니다.</p></li><li><p><strong>타이머 기능</strong>: 손을 감지한 후 일정 시간(예: 3초) 동안 뚜껑을 열어두고 자동으로 닫히게 할 수 있습니다.</p></li><li><p> 환경 보호에 관심이 많으신데, 이런 스마트 쓰레기통은 분리수거를 더 편리하게 만들어 환경 보호에 도움이 될 수 있어요. 또한 아두이노와 초음파 센서를 활용한 실제 프로젝트를 만들어보면서 IT 지식도 더 넓힐 수 있을 거예요!</p></li></ol><p>혹시 실제로 만들어보고 싶으시다면, 필요한 코드나 더 자세한 설명을 알려드릴 수 있어요.</p>]]></description>
         <enclosure url="" />
         <pubDate>2025-10-17 07:43:22 UTC</pubDate>
         <guid>https://padlet.com/jdes2/kz4evb76orqzh2jj/wish/3637258972</guid>
      </item>
      <item>
         <title>아직 테스트 안해본 코드</title>
         <author>11noohij</author>
         <link>https://padlet.com/jdes2/kz4evb76orqzh2jj/wish/3637538109</link>
         <description><![CDATA[<p>좋아, My son. 바로 가자.<br>요구사항 반영해서 <strong>아두이노 Nano + I2C LCD + 택트 스위치 + 서보</strong> 완전 구현 가능한 코드 만들어줄게.</p><p>🔹 코드 설명</p><ul><li><p><strong>NUM_BTN</strong>으로 버튼 개수 조절 가능</p></li><li><p><strong>display[]</strong> 배열: LCD에 표시할 문자 ('O' = 살아있음, 'X' = 누른 버튼)</p></li><li><p><strong>btnState[]</strong>: 버튼 눌림 상태 체크</p></li><li><p><strong>bombBtn</strong>: 랜덤 폭탄/악어 버튼</p></li><li><p><strong>서보 작동</strong>: 폭탄 터지면 지정 각도로 움직이고 초기화</p></li><li><p><strong>중복 방지</strong>: 이미 누른 버튼은 무시</p></li></ul><p>🔹 아두이노 코드</p><pre><code>#include &lt;Wire.h&gt;
#include &lt;LiquidCrystal_I2C.h&gt;
#include &lt;Servo.h&gt;

#define NUM_BTN 5          // 버튼 개수
const int btnPins[NUM_BTN] = {2,3,4,5,6};  // 버튼 핀
const int buzzer = 9;     // 버저 핀
#define SERVO_PIN 10       // 서보핀

LiquidCrystal_I2C lcd(0x20, 20, 4);  // I2C 주소 0x20, 20x4 LCD
Servo bombServo;

char display[NUM_BTN];     // LCD 표시 문자
int btnState[NUM_BTN];     // 버튼 상태 0=안눌림, 1=눌림
int bombBtn;               // 랜덤 폭탄/악어 버튼

void setup() {
  lcd.init();
  lcd.backlight();
  
  for(int i=0;i&lt;NUM_BTN;i++){
    pinMode(btnPins[i], INPUT_PULLUP);
    display[i] = 'O';
    btnState[i] = 0;
  }
  
  pinMode(buzzer, OUTPUT);
  bombServo.attach(SERVO_PIN);
  bombServo.write(0);      // 초기 위치

  randomSeed(analogRead(A0));
  bombBtn = random(0, NUM_BTN); // 폭탄 버튼 랜덤 선택

  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("Press a button!");
  updateLCD();
}

void loop() {
  for(int i=0;i&lt;NUM_BTN;i++){
    if(digitalRead(btnPins[i]) == LOW &amp;&amp; btnState[i]==0){ // 눌림 &amp; 아직 안눌림
      btnState[i] = 1;
      display[i] = 'X'; // LCD에 표시

      updateLCD();

      if(i == bombBtn){ // 폭탄 터짐
        lcd.setCursor(0,2);
        lcd.print("BOOM! Resetting...");
        tone(buzzer, 1000, 1000);   // 버저 1초
        bombServo.write(90);        // 서보 작동
        delay(1200);
        resetGame();                // 초기화
      } else { // 안전 버튼
        lcd.setCursor(0,2);
        lcd.print("Safe!        ");
        tone(buzzer, 400, 100);
        delay(300);
        lcd.setCursor(0,2);
        lcd.print("                "); // 메시지 지우기
      }
    }
  }
}

void updateLCD(){
  lcd.setCursor(0,1);
  for(int i=0;i&lt;NUM_BTN;i++){
    lcd.print(display[i]);
    lcd.print(' '); // 버튼 간 띄움
  }
}

void resetGame(){
  for(int i=0;i&lt;NUM_BTN;i++){
    btnState[i] = 0;
    display[i] = 'O';
  }
  bombBtn = random(0, NUM_BTN);
  bombServo.write(0);
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("Press a button!");
  updateLCD();
}
</code></pre><p>🔹 특징</p><ol><li><p>버튼 개수 바꾸고 싶으면 #define NUM_BTN 5만 바꾸면 됨</p></li><li><p>LCD 표시 문자 자유롭게 바꿀 수 있음 (O/X → ㄱ/ㄴ 등)</p></li><li><p>이미 누른 버튼은 다시 눌러도 작동 안 함</p></li><li><p>폭탄 터지면 <strong>서보 작동 + 버저 울림 + 초기화</strong></p></li><li><p>악어게임/폭탄게임 호환 가능 → bombBtn 랜덤 선택만 다르게 설정</p></li></ol><p>원하면 내가 여기에 <strong>중간에 ‘다음 라운드’ 버튼 눌러야 진행되는 기능</strong>이나<br><strong>폭탄 터질 때 LED 번쩍이게 하는 연출</strong>까지 추가해서 완전 미친 버전으로 만들어줄 수도 있음.</p><p>My son, 그거 넣어줄까?</p>]]></description>
         <enclosure url="" />
         <pubDate>2025-10-17 11:54:57 UTC</pubDate>
         <guid>https://padlet.com/jdes2/kz4evb76orqzh2jj/wish/3637538109</guid>
      </item>
      <item>
         <title></title>
         <author></author>
         <link>https://padlet.com/jdes2/kz4evb76orqzh2jj/wish/3640572839</link>
         <description><![CDATA[<p>import Entry</p><p>import arduino</p><p>import time</p><p>CHICK_START_X = -100</p><p>CHICK_START_Y = -50</p><p>CHICK_JUMP_HEIGHT = 80</p><p>CHICK_JUMP_DURATION = 0.5</p><p>OBSTACLE_START_X = 200</p><p>OBSTACLE_SPEED = 10</p><p>OBSTACLE_GENERATE_INTERVAL = 1.5</p><p>JUMP_BUTTON_PIN = 8</p><p>BUZZER_PIN = 7</p><p>board = arduino.Arduino() </p><p>score = 0</p><p>game_running = False</p><p>chick_is_jumping = False</p><p>obstacles = []</p><p>obstacle_counter = 0</p><p>chick = Entry.Sprite("병아리1")</p><p>obstacle_template = Entry.Sprite("장애물1")</p><p>chick.set_xy(CHICK_START_X, CHICK_START_Y)</p><p>obstacle_template.hide()</p><p>score_text = Entry.Text("점수: 0", font_size==25, color=="black")</p><p>score_text.set_xy(Entry.Canvas.width() / 2 - 50, Entry.Canvas.height() / 2 - 50)</p><p>game_over_text = Entry.Text("GAME OVER!", font_size==40, color=="red")</p><p>game_over_text.set_xy(0, 0)</p><p>game_over_text.hide()</p><p>start_text = Entry.Text("병아리 런 게임!\n(버튼을 눌러 시작!)", font_size==30, color=="blue")</p><p>start_text.set_xy(0, 0)</p><p>board.set_pin_mode(JUMP_BUTTON_PIN, arduino.INPUT_PULLUP)</p><p>board.set_pin_mode(BUZZER_PIN, arduino.OUTPUT)</p><p>def play_jump_sound():</p><p>    board.analog_write(BUZZER_PIN, 128)</p><p>    time.sleep(0.1)</p><p>    board.analog_write(BUZZER_PIN, 0)</p><p>def play_game_over_sound():</p><p>    for _ in range(3):</p><p>        board.analog_write(BUZZER_PIN, 150)</p><p>        time.sleep(0.2)</p><p>        board.analog_write(BUZZER_PIN, 0)</p><p>        time.sleep(0.1)</p><p>def chick_jump():</p><p>    global chick_is_jumping</p><p>    if not chick_is_jumping and game_running:</p><p>        chick_is_jumping = True</p><p>        play_jump_sound()</p><p>        </p><p>        Entry.Sprite.set_y_target(chick, CHICK_START_Y + CHICK_JUMP_HEIGHT, CHICK_JUMP_DURATION / 2)</p><p>        Entry.Sprite.set_y_target(chick, CHICK_START_Y, CHICK_JUMP_DURATION / 2, delay=CHICK_JUMP_DURATION / 2, callback=lambda: set_chick_not_jumping())</p><p>        </p><p>def set_chick_not_jumping():</p><p>    global chick_is_jumping</p><p>    chick_is_jumping = False</p><p>def generate_obstacle():</p><p>    global obstacle_counter</p><p>    if not game_running:</p><p>        return</p><p>    new_obstacle = Entry.Sprite(obstacle_template.image)</p><p>    new_obstacle.set_xy(OBSTACLE_START_X, CHICK_START_Y)</p><p>    obstacles.append(new_obstacle)</p><p>    </p><p>    next_interval = max(0.8, OBSTACLE_GENERATE_INTERVAL - obstacle_counter * 0.05)</p><p>    obstacle_counter += 1</p><p>    </p><p>    Entry.Timer(generate_obstacle, next_interval).start()</p><p>def check_collision():</p><p>    global game_running</p><p>    for obs in obstacles:</p><p>        if <a rel="noopener noreferrer nofollow" href="http://obs.is">obs.is</a>_visible() and <a rel="noopener noreferrer nofollow" href="http://chick.is">chick.is</a>_colliding_with(obs): </p><p>            game_running = False</p><p>            play_game_over_sound()</p><p>            end_game()</p><p>            return</p><p>    </p><p>def end_game():</p><p>    global game_running</p><p>    game_running = False</p><p>    game_over_<a rel="noopener noreferrer nofollow" href="http://text.show">text.show</a>()</p><p>    start_text.set_text(f"최종 점수: {score}\n(버튼을 눌러 다시 시작!)") </p><p>    start_<a rel="noopener noreferrer nofollow" href="http://text.show">text.show</a>()</p><p>    for obs in obstacles:</p><p>        obs.stop_all_motion()</p><p>        obs.hide()</p><p>    obstacles.clear()</p><p>    Entry.Timer.stop_all()</p><p>def game_loop():</p><p>    global score, game_running</p><p>    if not game_running:</p><p>        return</p><p>    score += 1</p><p>    score_text.set_text(f"점수: {score}")</p><p>    for obs in list(obstacles):</p><p>        obs.change_x(-OBSTACLE_SPEED)</p><p>        if obs.get_x() &lt; -OBSTACLE_START_X:</p><p>            obs.hide()</p><p>            obstacles.remove(obs)</p><p>    check_collision()</p><p>    Entry.repeat_loop(game_loop, 0.03)</p><p>def start_game():</p><p>    global score, game_running, obstacle_counter</p><p>    score = 0</p><p>    obstacle_counter = 0</p><p>    game_running = True</p><p>    chick_is_jumping = False</p><p>    chick.set_xy(CHICK_START_X, CHICK_START_Y)</p><p>    score_text.set_text("점수: 0")</p><p>    game_over_text.hide()</p><p>    start_text.hide()</p><p>    </p><p>    for obs in obstacles:</p><p>        obs.hide()</p><p>    obstacles.clear()</p><p>    </p><p>    Entry.Timer(generate_obstacle, OBSTACLE_GENERATE_INTERVAL).start()</p><p>    </p><p>    Entry.repeat_loop(game_loop, 0.03)</p><p>def check_button():</p><p>    global game_running</p><p>    button_state = <a rel="noopener noreferrer nofollow" href="http://board.digital">board.digital</a>_read(JUMP_BUTTON_PIN)</p><p>    </p><p>    if button_state == arduino.LOW:</p><p>        if not game_running:</p><p>            start_text.hide()</p><p>            start_game()</p><p>        else:</p><p>            chick_jump()</p><p>    </p><p>    Entry.Timer(check_button, 0.05).start()</p><p>Entry.on_start(lambda: [</p><p>    chick.set_xy(CHICK_START_X, CHICK_START_Y),</p><p>    obstacle_template.hide(),</p><p>    start_<a rel="noopener noreferrer nofollow" href="http://text.show">text.show</a>(),</p><p>    check_button()</p><p>])</p><p>Entry.start()</p><p><br/></p>]]></description>
         <enclosure url="" />
         <pubDate>2025-10-20 07:44:53 UTC</pubDate>
         <guid>https://padlet.com/jdes2/kz4evb76orqzh2jj/wish/3640572839</guid>
      </item>
      <item>
         <title>수정 코드</title>
         <author>snue0108</author>
         <link>https://padlet.com/jdes2/kz4evb76orqzh2jj/wish/3640585488</link>
         <description><![CDATA[<p>import Entry</p><p>import arduino</p><p>import time</p><p># 핀 설정</p><p>TRIG_PIN = 8</p><p>ECHO_PIN = 7</p><p>BUZZER_PIN = 10</p><p># 하드웨어 초기화</p><p>board = arduino.Arduino()</p><p>board.set_pin_mode(TRIG_PIN, arduino.OUTPUT)</p><p>board.set_pin_mode(ECHO_PIN, arduino.INPUT)</p><p>board.set_pin_mode(BUZZER_PIN, arduino.OUTPUT)</p><p><a rel="noopener noreferrer nofollow" href="http://board.digital">board.digital</a>_write(BUZZER_PIN, arduino.LOW)</p><p># 화면용 텍스트(간단한 LCD 대체)</p><p>line1 = Entry.Text("", font_size=25, color="black")  # 1행</p><p>line1.set_xy(0, 0)</p><p>line2 = Entry.Text("", font_size=25, color="black")  # 2행</p><p>line2.set_xy(0, 40)</p><p># 유틸: LCD처럼 텍스트를 쓰는 함수</p><p>def lcd_clear():</p><p>    line1.set_text("")</p><p>    line2.set_text("")</p><p>def lcd_print_line(n, txt):</p><p>    if n == 0:</p><p>        line1.set_text(txt)</p><p>    else:</p><p>        line2.set_text(txt)</p><p># 초음파 측정 함수(타임아웃 발생 시 9999 반환)</p><p>def get_ultrasonic_value(trig_pin, echo_pin):</p><p>    # 트리거 펄스 발생</p><p>    <a rel="noopener noreferrer nofollow" href="http://board.digital">board.digital</a>_write(trig_pin, arduino.LOW)</p><p>    time.sleep(0.002)  # 안정화</p><p>    <a rel="noopener noreferrer nofollow" href="http://board.digital">board.digital</a>_write(trig_pin, arduino.HIGH)</p><p>    time.sleep(0.00001)  # 10us</p><p>    <a rel="noopener noreferrer nofollow" href="http://board.digital">board.digital</a>_write(trig_pin, arduino.LOW)</p><p>    # 에코 시작 대기 (타임아웃)</p><p>    start_wait = time.time()</p><p>    timeout = 0.05  # 50ms 타임아웃 (가까운 거리 우선)</p><p>    while <a rel="noopener noreferrer nofollow" href="http://board.digital">board.digital</a>_read(echo_pin) == arduino.LOW:</p><p>        if time.time() - start_wait &gt; timeout:</p><p>            return 9999</p><p>    pulse_start = time.time()</p><p>    # 에코 끝 대기 (타임아웃)</p><p>    while <a rel="noopener noreferrer nofollow" href="http://board.digital">board.digital</a>_read(echo_pin) == arduino.HIGH:</p><p>        if time.time() - pulse_start &gt; 0.05:</p><p>            # 비정상적으로 긴 펄스 -&gt; 실패 처리</p><p>            return 9999</p><p>    pulse_end = time.time()</p><p>    pulse_duration = pulse_end - pulse_start  # 초 단위</p><p>    # 거리 계산: (시간 * 음속(34300 cm/s)) / 2</p><p>    distance_cm = (pulse_duration * 34300) / 2</p><p>    return distance_cm</p><p># 부저 제어: freq(Hz), duration(초). freq &lt;= 0 이면 OFF</p><p>def set_buzzer(pin, freq, duration):</p><p>    if freq &lt;= 0 or duration &lt;= 0:</p><p>        <a rel="noopener noreferrer nofollow" href="http://board.digital">board.digital</a>_write(pin, arduino.LOW)</p><p>        return</p><p>    period = 1.0 / freq</p><p>    half = period / 2.0</p><p>    end_time = time.time() + duration</p><p>    # 단순 토글로 소리내기 (짧은 duration에서만 사용 권장)</p><p>    while time.time() &lt; end_time:</p><p>        <a rel="noopener noreferrer nofollow" href="http://board.digital">board.digital</a>_write(pin, arduino.HIGH)</p><p>        time.sleep(half)</p><p>        <a rel="noopener noreferrer nofollow" href="http://board.digital">board.digital</a>_write(pin, arduino.LOW)</p><p>        time.sleep(half)</p><p>    <a rel="noopener noreferrer nofollow" href="http://board.digital">board.digital</a>_write(pin, arduino.LOW)</p><p># 초기 메시지</p><p>lcd_clear()</p><p>lcd_print_line(0, "Rear Sensor Init")</p><p>time.sleep(2)</p><p>lcd_clear()</p><p># 메인 루프: Entry.repeat_loop으로 주기 실행</p><p>def sensor_loop():</p><p>    distance = get_ultrasonic_value(TRIG_PIN, ECHO_PIN)</p><p>    if distance == 9999:</p><p>        lcd_print_line(0, "Distance: -- cm")</p><p>    else:</p><p>        lcd_print_line(0, "Distance: " + str(int(distance)) + " cm")</p><p>    # 경고/부저 처리 (원래 로직 반영)</p><p>    if distance &lt; 20:</p><p>        # Danger</p><p>        lcd_print_line(1, "!!! DANGER !!!")</p><p>        set_buzzer(BUZZER_PIN, 1000, 0.1)</p><p>    elif distance &lt; 50:</p><p>        lcd_print_line(1, "--- Caution! ---")</p><p>        set_buzzer(BUZZER_PIN, 800, 0.2)</p><p>    elif distance &lt; 100:</p><p>        lcd_print_line(1, " Object Detect ")</p><p>        set_buzzer(BUZZER_PIN, 600, 0.3)</p><p>    else:</p><p>        lcd_print_line(1, "   Safe Zone   ")</p><p>        # 부저 끄기(없으면 LOW 유지)</p><p>        <a rel="noopener noreferrer nofollow" href="http://board.digital">board.digital</a>_write(BUZZER_PIN, arduino.LOW)</p><p># 엔트리 반복 실행: 센서 읽기 주기(초)를 적절히 설정</p><p>Entry.repeat_loop(sensor_loop, 0.2)</p><p>Entry.start()</p>]]></description>
         <enclosure url="" />
         <pubDate>2025-10-20 07:53:32 UTC</pubDate>
         <guid>https://padlet.com/jdes2/kz4evb76orqzh2jj/wish/3640585488</guid>
      </item>
      <item>
         <title>ㅁ</title>
         <author></author>
         <link>https://padlet.com/jdes2/kz4evb76orqzh2jj/wish/3640608843</link>
         <description><![CDATA[<p>#include &lt;Wire.h&gt;               // I2C 통신을 위한 라이브러리</p><p>#include &lt;LiquidCrystal_I2C.h&gt;  // I2C LCD 제어를 위한 라이브러리</p><p>// --- 핀 설정 ---</p><p>const int TACT_SWITCH_PIN = 2; // 텍트 스위치 핀 (2번 디지털 핀)</p><p>// LCD 설정 (LCD 모듈 주소와 열/행 수)</p><p>// !!! 자신의 LCD 모듈 주소를 확인해주세요. (주로 0x27 또는 0x3F) !!!</p><p>// 정확한 주소를 모르면 "Arduino I2C Scanner" 스케치를 검색하여 실행해보세요.</p><p>// LiquidCrystal_I2C lcd(LCD 주소, 열 수, 행 수);</p><p>LiquidCrystal_I2C lcd(0x27, 16, 2); // 16x2 LCD 기준 (만약 20x4 LCD면 LiquidCrystal_I2C lcd(0x27, 20, 4); 와 같이 변경)</p><p>// --- 게임 변수 ---</p><p>enum GameState { WAITING, PLAYING, GAME_OVER }; // 게임 상태</p><p>GameState currentGameState = WAITING;</p><p>long score = 0;           // 점수</p><p>unsigned long lastObstacleTime = 0; // 마지막 장애물 생성 시간</p><p>const int OBSTACLE_INTERVAL_MIN = 1500; // 장애물 최소 생성 간격 (ms)</p><p>const int OBSTACLE_INTERVAL_MAX = 2500; // 장애물 최대 생성 간격 (ms)</p><p>unsigned long nextObstacleTime = 0; // 다음 장애물 생성 시간</p><p>// 병아리 위치 및 점프 관련</p><p>int chickPos = 0;          // 병아리의 수직 위치 (0이 바닥)</p><p>float chickVelocity = 0;   // 병아리의 수직 속도</p><p>const float JUMP_VELOCITY = 2.5; // 점프 시 초기 속도</p><p>const float GRAVITY = -0.05; // 중력 가속도 (음수 값)</p><p>const int GROUND_LEVEL = 0; // 바닥 레벨 (LCD 2번째 줄)</p><p>// 장애물 위치 및 속도 관련</p><p>int obstaclePos = 15;      // 장애물 수평 위치 (LCD 16칸 기준 0~15)</p><p>const int OBSTACLE_WIDTH = 1; // 장애물 폭 (1칸)</p><p>int obstacleSpeedFactor = 4; // 장애물 이동 속도 (값이 작을수록 빠름)</p><p>int obstacleMoveCounter = 0; // 장애물 이동 카운터</p><p>const int MAX_OBSTACLE_SPEED_FACTOR = 1; // 최대 속도 (1까지 줄어들면 가장 빠름)</p><p>// 텍트 스위치 디바운싱 관련</p><p>unsigned long lastDebounceTime = 0; // 마지막 디바운스 시간</p><p>unsigned long debounceDelay = 50;   // 디바운스 딜레이 (ms)</p><p>int lastButtonState = HIGH;         // 이전 버튼 상태 (INPUT_PULLUP이므로 HIGH가 안 눌림)</p><p>int currentButtonState;             // 현재 버튼 상태</p><p>bool buttonPressedFlag = false;     // 버튼이 눌렸는지 확인하는 플래그 (loop에서 한번만 처리)</p><p>// --- 캐릭터 및 장애물 모양 (LCD용 커스텀 캐릭터) ---</p><p>byte chickChar[8] = {</p><p>  B00000, // 이 부분은 LCD 특성상 시뮬레이션에서 표시가 어려울 수 있으나, 실제 LCD에는 보입니다.</p><p>  B00000, // 위 아래 2칸 정도 비워둔 이유는 LCD 특성상 그림을 그릴 수 있는 픽셀이 제한적이기 때문입니다.</p><p>  B00110,</p><p>  B01111,</p><p>  B11110,</p><p>  B01100,</p><p>  B00100,</p><p>  B00000</p><p>}; // 병아리 모양 (간단하게 표현)</p><p>byte obstacleChar[8] = {</p><p>  B00000,</p><p>  B01110,</p><p>  B01110,</p><p>  B01110,</p><p>  B01110,</p><p>  B01110,</p><p>  B01110,</p><p>  B00000</p><p>}; // 장애물 모양</p><p>// --- 함수 선언 (사용하기 전에 미리 정의) ---</p><p>void resetGame();</p><p>void checkButtonState(); // 함수 이름을 buttonPressedFlag와 겹치지 않게 수정</p><p>void updateGameLogic();</p><p>void drawGameScreen();</p><p>bool checkCollision();</p><p>void lcdPrintCenter(int row, String text);</p><p>void setup() {</p><p>  Serial.begin(9600); // 디버깅을 위한 시리얼 통신 시작</p><p>  lcd.init();         // LCD 초기화</p><p>  lcd.backlight();    // LCD 백라이트 켜기</p><p>  // 커스텀 캐릭터 생성 (0번 위치에 병아리, 1번 위치에 장애물)</p><p>  lcd.createChar(0, chickChar);</p><p>  lcd.createChar(1, obstacleChar);</p><p>  // 텍트 스위치 핀을 입력으로 설정하고 내부 풀업 저항 사용</p><p>  pinMode(TACT_SWITCH_PIN, INPUT_PULLUP);</p><p>  resetGame(); // 게임 초기화 및 시작 대기 메시지 표시</p><p>}</p><p>void loop() {</p><p>  checkButtonState(); // 버튼 상태 감지 및 buttonPressedFlag 업데이트</p><p>  switch (currentGameState) {</p><p>    case WAITING:</p><p>      // 버튼이 눌리면 게임 시작</p><p>      if (buttonPressedFlag) {</p><p>        currentGameState = PLAYING;</p><p>        resetGame(); // 게임 변수 초기화 및 게임 시작 준비</p><p>      }</p><p>      break;</p><p>    case PLAYING:</p><p>      updateGameLogic(); // 게임 로직 업데이트 (움직임, 점수 등)</p><p>      drawGameScreen();   // LCD에 게임 화면 그리기</p><p>      // 충돌 확인</p><p>      if (checkCollision()) {</p><p>        currentGameState = GAME_OVER;</p><p>      }</p><p>      break;</p><p>    case GAME_OVER:</p><p>      // 버튼이 눌리면 다시 시작 대기 상태로 전환</p><p>      if (buttonPressedFlag) {</p><p>        currentGameState = WAITING;</p><p>        resetGame(); // 초기 메시지 다시 표시</p><p>      }</p><p>      break;</p><p>  }</p><p>}</p><p>// --- 게임 함수 정의 ---</p><p>// 게임 상태를 초기화하고 초기 메시지 표시</p><p>void resetGame() {</p><p>  score = 0;</p><p>  chickPos = GROUND_LEVEL; // 병아리 위치를 바닥으로</p><p>  chickVelocity = 0;</p><p>  obstaclePos = 15;        // 장애물은 화면 오른쪽 밖에서 시작</p><p>  obstacleSpeedFactor = 4; // 장애물 속도 초기화</p><p>  obstacleMoveCounter = 0;</p><p>  </p><p>  // 다음 장애물 생성 시간 설정 (시작 시점에만 설정하고, 이후는 updateGameLogic에서)</p><p>  nextObstacleTime = millis() + random(OBSTACLE_INTERVAL_MIN, OBSTACLE_INTERVAL_MAX); </p><p>  lcd.clear(); // LCD 화면 지우기</p><p>  if (currentGameState == WAITING) {</p><p>    lcdPrintCenter(0, "Chick Jump!");</p><p>    lcdPrintCenter(1, "Press Button!");</p><p>  } else if (currentGameState == GAME_OVER) {</p><p>    // GAME_OVER 상태에서 resetGame이 호출되는 경우는 재시작을 위함</p><p>    lcdPrintCenter(0, "GAME OVER!");</p><p>    String finalScore = "Score: " + String(score); // 현재 점수 표시</p><p>    lcdPrintCenter(1, finalScore);</p><p>  }</p><p>  delay(100); // 메시지 잠시 표시</p><p>}</p><p>// 텍트 스위치 상태를 확인하고 디바운싱 처리</p><p>void checkButtonState() {</p><p>  int reading = digitalRead(TACT_SWITCH_PIN); // 버튼 핀 상태 읽기</p><p>  // 버튼 상태가 바뀌었으면 디바운스 타이머 시작</p><p>  if (reading != lastButtonState) {</p><p>    lastDebounceTime = millis();</p><p>  }</p><p>  // 디바운스 시간이 지나고, 현재 버튼 상태가 안정되면</p><p>  if ((millis() - lastDebounceTime) &gt; debounceDelay) {</p><p>    if (reading != currentButtonState) {</p><p>      currentButtonState = reading;</p><p>      // LOW = 눌린 상태 (INPUT_PULLUP 사용)</p><p>      if (currentButtonState == LOW) {</p><p>        buttonPressedFlag = true; // 버튼 눌림 플래그 설정</p><p>      } else {</p><p>        buttonPressedFlag = false; // 버튼 안 눌림 플래그 해제</p><p>      }</p><p>    }</p><p>  }</p><p>  lastButtonState = reading; // 이전 버튼 상태 저장</p><p>}</p><p>// 게임의 논리적인 부분(움직임, 점수, 장애물 생성) 업데이트</p><p>void updateGameLogic() {</p><p>  // --- 병아리 움직임 (중력 적용 및 점프) ---</p><p>  chickVelocity += GRAVITY; // 중력 적용</p><p>  chickPos += round(chickVelocity); // 위치 업데이트</p><p>  // 바닥 아래로 내려가지 않도록 고정</p><p>  if (chickPos &lt;= GROUND_LEVEL) {</p><p>    chickPos = GROUND_LEVEL;</p><p>    chickVelocity = 0; // 땅에 닿으면 속도 0</p><p>  }</p><p>  // 점프 처리 (버튼이 눌리고, 병아리가 바닥에 있을 때만 점프 가능)</p><p>  if (buttonPressedFlag &amp;&amp; chickPos == GROUND_LEVEL) {</p><p>    chickVelocity = JUMP_VELOCITY;</p><p>    buttonPressedFlag = false; // 한 번 점프하면 플래그 초기화</p><p>  } else if (buttonPressedFlag) { // 바닥이 아닌데 눌린 경우 (예: 게임 시작)</p><p>    buttonPressedFlag = false; // 플래그 초기화</p><p>  }</p><p>  // --- 장애물 움직임 및 생성 ---</p><p>  // obstacleSpeedFactor 값에 따라 장애물이 움직이는 간격을 조절 (값이 작을수록 빠름)</p><p>  if ((millis() % obstacleSpeedFactor) == 0) { // 매번 1ms마다 움직이지 않고 속도 계수에 따라</p><p>    obstacleMoveCounter++;</p><p>    if (obstacleMoveCounter &gt;= 10) { // 예를 들어 10번 주기로 움직이게</p><p>        obstaclePos--;</p><p>        obstacleMoveCounter = 0;</p><p>    }</p><p>  }</p><p>  // 장애물이 화면 왼쪽 끝 밖으로 나가면 다시 오른쪽에서 생성</p><p>  if (obstaclePos &lt; -OBSTACLE_WIDTH) { // 장애물이 화면 밖으로 나갔으면</p><p>      obstaclePos = 15; // 화면 오른쪽 끝 (15열)에서 다시 시작</p><p>      score++; // 장애물 넘을 때마다 점수 증가!</p><p>      </p><p>      // 점수가 높아지면 장애물 속도 증가 (obstacleSpeedFactor 감소)</p><p>      if (obstacleSpeedFactor &gt; MAX_OBSTACLE_SPEED_FACTOR) {</p><p>          obstacleSpeedFactor--; // 값을 1씩 줄여서 빠르게 만듦</p><p>      }</p><p>  }</p><p>}</p><p>// LCD 화면에 게임 상태 그리기</p><p>void drawGameScreen() {</p><p>  lcd.clear(); // 매번 화면을 지우고 다시 그려서 움직임을 표현</p><p>  // --- 병아리 그리기 (0번 커스텀 캐릭터) ---</p><p>  // chickPos는 현재 병아리의 '수직 위치'를 나타내는데, 0이면 2번째 줄, 1 이상이면 1번째 줄로 표시</p><p>  if (chickPos == GROUND_LEVEL) { // 병아리가 바닥에 있을 때 (LCD 2번째 줄)</p><p>      lcd.setCursor(1, 1); // 1열(0부터 시작) 2번째 줄(1부터 시작)</p><p>      lcd.write(byte(0)); // 0번 커스텀 캐릭터 (병아리) 출력</p><p>  } else { // 병아리가 점프 중일 때 (LCD 1번째 줄)</p><p>      lcd.setCursor(1, 0); // 1열 1번째 줄</p><p>      lcd.write(byte(0)); // 0번 커스텀 캐릭터 (병아리) 출력</p><p>  }</p><p>  // --- 장애물 그리기 (1번 커스텀 캐릭터) ---</p><p>  // obstaclePos는 현재 장애물의 '수평 위치' (0~15)</p><p>  // 장애물은 항상 LCD 2번째 줄(바닥)에 그립니다.</p><p>  if (obstaclePos &gt;= 0 &amp;&amp; obstaclePos &lt; 16) { // 장애물이 화면 안에 있을 때만 그리기</p><p>      lcd.setCursor(obstaclePos, 1); // 현재 장애물 위치, 2번째 줄</p><p>      lcd.write(byte(1)); // 1번 커스텀 캐릭터 (장애물) 출력</p><p>  }</p><p>  // --- 점수 표시 ---</p><p>  // LCD 우측 상단에 점수 표시</p><p>  lcd.setCursor(12, 0); // 13번째 열(12), 1번째 줄(0)</p><p>  lcd.print(score);</p><p>  delay(50); // 게임 속도 조절 (너무 빠르면 눈에 갱신이 보이지 않거나 CPU 부하)</p><p>             // 이 딜레이가 게임의 '프레임 속도'와 비슷하게 작동해요!</p><p>}</p><p>// 병아리와 장애물의 충돌 여부 확인</p><p>bool checkCollision() {</p><p>  // 병아리 위치 (항상 1열)</p><p>  // 장애물 위치 (obstaclePos)</p><p>  // 병아리가 바닥(GROUND_LEVEL)에 있을 때, 장애물이 병아리 칸(1열)에 있으면 충돌</p><p>  if (chickPos <mark> GROUND_LEVEL &amp;&amp; (obstaclePos </mark> 1 || obstaclePos == 0)) { // 병아리가 1열, 장애물이 0열 또는 1열에 있을 때</p><p>    return true; // 충돌 발생!</p><p>  }</p><p>  return false; // 충돌 아님</p><p>}</p><p>// LCD 화면의 특정 행에 텍스트를 가운데 정렬하여 출력</p><p>void lcdPrintCenter(int row, String text) {</p><p>  lcd.setCursor(0, row); // 먼저 해당 줄로 이동해서 커서 초기화</p><p>  // 텍스트의 길이가 16칸보다 짧을 때만 가운데 정렬 계산</p><p>  if (text.length() &lt; 16) {</p><p>    int numSpaces = (16 - text.length()) / 2;</p><p>    for (int i = 0; i &lt; numSpaces; i++) {</p><p>      lcd.print(" "); // 앞쪽에 공백을 채워 가운데 정렬</p><p>    }</p><p>  }</p><p>  lcd.print(text); // 텍스트 출력</p><p>}</p>]]></description>
         <enclosure url="" />
         <pubDate>2025-10-20 08:13:06 UTC</pubDate>
         <guid>https://padlet.com/jdes2/kz4evb76orqzh2jj/wish/3640608843</guid>
      </item>
      <item>
         <title></title>
         <author></author>
         <link>https://padlet.com/jdes2/kz4evb76orqzh2jj/wish/3640619509</link>
         <description><![CDATA[<p>#include &lt;Wire.h&gt;               // I2C 통신을 위한 라이브러리</p><p>#include &lt;LiquidCrystal_I2C.h&gt;  // I2C LCD 제어를 위한 라이브러리</p><p>// --- 핀 설정 ---</p><p>const int TACT_SWITCH_PIN = 2; // 텍트 스위치 핀 (2번 디지털 핀)</p><p>// LCD 설정 (LCD 모듈 주소와 열/행 수)</p><p>// !!! 자신의 LCD 모듈 주소를 확인해주세요. (주로 0x27 또는 0x3F) !!!</p><p>// 이전에 '0x27'로 해보고 안 되면 '0x3F'로 바꿔서 다시 업로드해보세요.</p><p>// 정확한 주소를 모르면 "Arduino I2C Scanner" 스케치를 검색하여 실행해보세요.</p><p>LiquidCrystal_I2C lcd(0x27, 16, 2); // 16x2 LCD 기준 (만약 20x4 LCD면 LiquidCrystal_I2C lcd(0x27, 20, 4); 와 같이 변경)</p><p>// --- 게임 변수 ---</p><p>enum GameState { WAITING, PLAYING, GAME_OVER }; // 게임 상태 정의</p><p>GameState currentGameState = WAITING; // 초기 게임 상태는 시작 대기</p><p>long score = 0;           // 현재 점수</p><p>unsigned long lastObstacleSpawnTime = 0; // 마지막 장애물이 생성된 시간</p><p>const int OBSTACLE_SPAWN_INTERVAL_MIN = 1500; // 장애물 최소 생성 간격 (밀리초)</p><p>const int OBSTACLE_SPAWN_INTERVAL_MAX = 2500; // 장애물 최대 생성 간격 (밀리초)</p><p>unsigned long nextObstacleSpawnTime = 0; // 다음 장애물이 생성될 시간</p><p>// 병아리 위치 및 점프 관련 변수</p><p>int chickVerticalPos = 0;          // 병아리의 수직 위치 (0이 바닥)</p><p>float chickJumpVelocity = 0;       // 병아리의 수직 속도</p><p>const float JUMP_POWER = 2.5;      // 점프 시 초기 속도 강도</p><p>const float GRAVITY_ACCEL = -0.05; // 중력 가속도 (음수 값으로 아래 방향)</p><p>const int GROUND_LEVEL = 0;        // 병아리가 서 있을 바닥 레벨 (LCD 2번째 줄에 해당)</p><p>// 장애물 위치 및 속도 관련 변수</p><p>int obstacleHorizontalPos = 15;      // 장애물 수평 위치 (LCD 16칸 기준 0~15열)</p><p>const int OBSTACLE_SPRITE_WIDTH = 1; // 장애물 캐릭터가 차지하는 폭 (1칸)</p><p>int obstacleMoveSpeedFactor = 4;     // 장애물 이동 속도 조절 (값이 작을수록 빠름, 1이 가장 빠름)</p><p>int obstacleMoveCounter = 0;         // 장애물 이동 주기 카운터</p><p>const int MAX_SPEED_FACTOR = 1;      // 장애물 최대 속도 (speedFactor가 이 값까지 도달하면 가장 빠름)</p><p>// 텍트 스위치 디바운싱 관련 변수 (버튼이 한 번 눌린 것으로 정확히 인식하도록)</p><p>unsigned long lastButtonDebounceTime = 0; // 마지막 버튼 디바운스 체크 시간</p><p>unsigned long debounceDelay = 50;         // 디바운스 지연 시간 (밀리초)</p><p>int lastButtonPhysicalState = HIGH;       // 이전 버튼의 물리적 상태 (INPUT_PULLUP이므로 HIGH가 안 눌림)</p><p>int currentButtonStableState;             // 현재 안정적인 버튼 상태</p><p>bool isButtonPressedThisCycle = false;    // 현재 루프에서 버튼이 눌렸음을 나타내는 플래그</p><p>// --- LCD용 커스텀 캐릭터 데이터 ---</p><p>// 병아리 모양 데이터 (5x8 픽셀)</p><p>byte chickCharacter[8] = {</p><p>  B00000, // 맨 위 픽셀 줄 (비워둠)</p><p>  B00000, // 그 다음 픽셀 줄 (비워둠)</p><p>  B00110, // 머리</p><p>  B01111, // 몸통</p><p>  B11110, // 날개</p><p>  B01100, // 다리1</p><p>  B00100, // 다리2</p><p>  B00000  // 맨 아래 픽셀 줄 (비워둠)</p><p>}; </p><p>// 장애물 모양 데이터 (5x8 픽셀)</p><p>byte obstacleCharacter[8] = {</p><p>  B00000,</p><p>  B01110, // 상단</p><p>  B01110,</p><p>  B01110,</p><p>  B01110,</p><p>  B01110,</p><p>  B01110, // 하단</p><p>  B00000</p><p>};</p><p>// --- 함수 선언 ---</p><p>void setupGame();            // 게임 초기 설정</p><p>void readButtonState();      // 버튼 상태 읽기 및 디바운싱 처리</p><p>void updateGameLogic();      // 게임의 논리적 업데이트 (움직임, 점수 등)</p><p>void drawGameScreen();       // LCD에 게임 화면 그리기</p><p>bool checkCollisionStatus(); // 병아리와 장애물의 충돌 여부 확인</p><p>void printTextCentered(int row, String text); // LCD에 텍스트를 가운데 정렬하여 출력</p><p>// --- Arduino setup 함수 (최초 1회 실행) ---</p><p>void setup() {</p><p>  Serial.begin(9600); // 시리얼 모니터를 통한 디버깅을 위해 시리얼 통신 시작</p><p>  lcd.init();         // LCD 모듈 초기화</p><p>  lcd.backlight();    // LCD 백라이트 켜기</p><p>  // 커스텀 캐릭터를 LCD 메모리에 생성 (0번 위치에 병아리, 1번 위치에 장애물)</p><p>  lcd.createChar(0, chickCharacter);</p><p>  lcd.createChar(1, obstacleCharacter);</p><p>  // 텍트 스위치 핀을 입력 모드로 설정하고, 내부 풀업 저항을 활성화</p><p>  pinMode(TACT_SWITCH_PIN, INPUT_PULLUP);</p><p>  setupGame(); // 게임의 초기 상태 설정</p><p>}</p><p>// --- Arduino loop 함수 (반복 실행) ---</p><p>void loop() {</p><p>  readButtonState(); // 매 루프마다 버튼 상태를 읽고 업데이트</p><p>  switch (currentGameState) {</p><p>    case WAITING: // 게임 시작 대기 상태</p><p>      // 버튼이 눌리면 게임 시작 상태로 전환하고 게임 변수 초기화</p><p>      if (isButtonPressedThisCycle) {</p><p>        currentGameState = PLAYING;</p><p>        setupGame(); // 게임 플레이를 위한 초기화</p><p>      </p>]]></description>
         <enclosure url="" />
         <pubDate>2025-10-20 08:21:52 UTC</pubDate>
         <guid>https://padlet.com/jdes2/kz4evb76orqzh2jj/wish/3640619509</guid>
      </item>
   </channel>
</rss>
