unsloth/DeepSeek-R1-GGUF DeepSeek-R1-UD-IQ1_S を自宅サーバで動かす
ということで、自宅のCore i9-13900KF, RTX-3090(24G)+RTX4060Ti(16G)+Memory128GBのマシンで、Unsloth AIさんの1.58bit deepseek-R1が動いたので、その時のログとか。
とりあえず、pythonでハングマンゲームを作ってもらった
ryuuri@RTX-3090:~/work/llama.cpp/llama.cpp.2/build/bin$ /home/ryuuri/work/llama.cpp/llama.cpp.2/build/bin/llama-cli -m /home/ryuuri/models/DeepSeek-R1-UD-IQ1_S/DeepSeek-R1-UD-IQ1_S-00001-of-00003.gguf -t 16 --temp 0.6 -p "pythonでハングマンゲーム
を作成してください" -n -1
ggml_cuda_init: GGML_CUDA_FORCE_MMQ: no
ggml_cuda_init: GGML_CUDA_FORCE_CUBLAS: no
ggml_cuda_init: found 2 CUDA devices:
Device 0: NVIDIA GeForce RTX 3090, compute capability 8.6, VMM: yes
Device 1: NVIDIA GeForce RTX 4060 Ti, compute capability 8.9, VMM: yes
build: 4426 (96a1dc27) with cc (Ubuntu 11.4.0-1ubuntu1~22.04) 11.4.0 for x86_64-linux-gnu
main: llama backend init
main: load the model and apply lora adapter, if any
llama_model_load_from_file: using device CUDA0 (NVIDIA GeForce RTX 3090) - 23306 MiB free
llama_model_load_from_file: using device CUDA1 (NVIDIA GeForce RTX 4060 Ti) - 15225 MiB free
llama_model_loader: additional 2 GGUFs metadata loaded.
llama_model_loader: loaded meta data with 52 key-value pairs and 1025 tensors from /home/ryuuri/models/DeepSeek-R1-UD-IQ1_S/DeepSeek-R1-UD-IQ1_S-00001-of-00003.gguf (version GGUF V3 (latest))
llama_model_loader: Dumping metadata keys/values. Note: KV overrides do not apply in this output.
llama_model_loader: - kv 0: general.architecture str = deepseek2
llama_model_loader: - kv 1: general.type str = model
llama_model_loader: - kv 2: general.name str = DeepSeek R1 BF16
llama_model_loader: - kv 3: general.quantized_by str = Unsloth
llama_model_loader: - kv 4: general.size_label str = 256x20B
llama_model_loader: - kv 5: general.repo_url str = https://huggingface.co/unsloth
llama_model_loader: - kv 6: deepseek2.block_count u32 = 61
llama_model_loader: - kv 7: deepseek2.context_length u32 = 163840
llama_model_loader: - kv 8: deepseek2.embedding_length u32 = 7168
llama_model_loader: - kv 9: deepseek2.feed_forward_length u32 = 18432
llama_model_loader: - kv 10: deepseek2.attention.head_count u32 = 128
llama_model_loader: - kv 11: deepseek2.attention.head_count_kv u32 = 128
llama_model_loader: - kv 12: deepseek2.rope.freq_base f32 = 10000.000000
llama_model_loader: - kv 13: deepseek2.attention.layer_norm_rms_epsilon f32 = 0.000001
llama_model_loader: - kv 14: deepseek2.expert_used_count u32 = 8
llama_model_loader: - kv 15: deepseek2.leading_dense_block_count u32 = 3
llama_model_loader: - kv 16: deepseek2.vocab_size u32 = 129280
llama_model_loader: - kv 17: deepseek2.attention.q_lora_rank u32 = 1536
llama_model_loader: - kv 18: deepseek2.attention.kv_lora_rank u32 = 512
llama_model_loader: - kv 19: deepseek2.attention.key_length u32 = 192
llama_model_loader: - kv 20: deepseek2.attention.value_length u32 = 128
llama_model_loader: - kv 21: deepseek2.expert_feed_forward_length u32 = 2048
llama_model_loader: - kv 22: deepseek2.expert_count u32 = 256
llama_model_loader: - kv 23: deepseek2.expert_shared_count u32 = 1
llama_model_loader: - kv 24: deepseek2.expert_weights_scale f32 = 2.500000
llama_model_loader: - kv 25: deepseek2.expert_weights_norm bool = true
llama_model_loader: - kv 26: deepseek2.expert_gating_func u32 = 2
llama_model_loader: - kv 27: deepseek2.rope.dimension_count u32 = 64
llama_model_loader: - kv 28: deepseek2.rope.scaling.type str = yarn
llama_model_loader: - kv 29: deepseek2.rope.scaling.factor f32 = 40.000000
llama_model_loader: - kv 30: deepseek2.rope.scaling.original_context_length u32 = 4096
llama_model_loader: - kv 31: deepseek2.rope.scaling.yarn_log_multiplier f32 = 0.100000
llama_model_loader: - kv 32: tokenizer.ggml.model str = gpt2
llama_model_loader: - kv 33: tokenizer.ggml.pre str = deepseek-v3
llama_model_loader: - kv 34: tokenizer.ggml.tokens arr[str,129280] = ["<|begin?of?sentence|>", "<・..
llama_model_loader: - kv 35: tokenizer.ggml.token_type arr[i32,129280] = [3, 3, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, ...
llama_model_loader: - kv 36: tokenizer.ggml.merges arr[str,127741] = ["? t", "? a", "i n", "? ?", "h e...
llama_model_loader: - kv 37: tokenizer.ggml.bos_token_id u32 = 0
llama_model_loader: - kv 38: tokenizer.ggml.eos_token_id u32 = 1
llama_model_loader: - kv 39: tokenizer.ggml.padding_token_id u32 = 128815
llama_model_loader: - kv 40: tokenizer.ggml.add_bos_token bool = true
llama_model_loader: - kv 41: tokenizer.ggml.add_eos_token bool = false
llama_model_loader: - kv 42: tokenizer.chat_template str = {% if not add_generation_prompt is de...
llama_model_loader: - kv 43: general.quantization_version u32 = 2
llama_model_loader: - kv 44: general.file_type u32 = 24
llama_model_loader: - kv 45: quantize.imatrix.file str = DeepSeek-R1.imatrix
llama_model_loader: - kv 46: quantize.imatrix.dataset str = /training_data/calibration_datav3.txt
llama_model_loader: - kv 47: quantize.imatrix.entries_count i32 = 720
llama_model_loader: - kv 48: quantize.imatrix.chunks_count i32 = 124
llama_model_loader: - kv 49: split.no u16 = 0
llama_model_loader: - kv 50: split.tensors.count i32 = 1025
llama_model_loader: - kv 51: split.count u16 = 3
llama_model_loader: - type f32: 361 tensors
llama_model_loader: - type q4_K: 190 tensors
llama_model_loader: - type q5_K: 116 tensors
llama_model_loader: - type q6_K: 184 tensors
llama_model_loader: - type iq2_xxs: 6 tensors
llama_model_loader: - type iq1_s: 168 tensors
llm_load_vocab: special_eos_id is not in special_eog_ids - the tokenizer config may be incorrect
llm_load_vocab: special tokens cache size = 819
llm_load_vocab: token to piece cache size = 0.8223 MB
llm_load_print_meta: format = GGUF V3 (latest)
llm_load_print_meta: arch = deepseek2
llm_load_print_meta: vocab type = BPE
llm_load_print_meta: n_vocab = 129280
llm_load_print_meta: n_merges = 127741
llm_load_print_meta: vocab_only = 0
llm_load_print_meta: n_ctx_train = 163840
llm_load_print_meta: n_embd = 7168
llm_load_print_meta: n_layer = 61
llm_load_print_meta: n_head = 128
llm_load_print_meta: n_head_kv = 128
llm_load_print_meta: n_rot = 64
llm_load_print_meta: n_swa = 0
llm_load_print_meta: n_embd_head_k = 192
llm_load_print_meta: n_embd_head_v = 128
llm_load_print_meta: n_gqa = 1
llm_load_print_meta: n_embd_k_gqa = 24576
llm_load_print_meta: n_embd_v_gqa = 16384
llm_load_print_meta: f_norm_eps = 0.0e+00
llm_load_print_meta: f_norm_rms_eps = 1.0e-06
llm_load_print_meta: f_clamp_kqv = 0.0e+00
llm_load_print_meta: f_max_alibi_bias = 0.0e+00
llm_load_print_meta: f_logit_scale = 0.0e+00
llm_load_print_meta: n_ff = 18432
llm_load_print_meta: n_expert = 256
llm_load_print_meta: n_expert_used = 8
llm_load_print_meta: causal attn = 1
llm_load_print_meta: pooling type = 0
llm_load_print_meta: rope type = 0
llm_load_print_meta: rope scaling = yarn
llm_load_print_meta: freq_base_train = 10000.0
llm_load_print_meta: freq_scale_train = 0.025
llm_load_print_meta: n_ctx_orig_yarn = 4096
llm_load_print_meta: rope_finetuned = unknown
llm_load_print_meta: ssm_d_conv = 0
llm_load_print_meta: ssm_d_inner = 0
llm_load_print_meta: ssm_d_state = 0
llm_load_print_meta: ssm_dt_rank = 0
llm_load_print_meta: ssm_dt_b_c_rms = 0
llm_load_print_meta: model type = 671B
llm_load_print_meta: model ftype = IQ1_S - 1.5625 bpw
llm_load_print_meta: model params = 671.03 B
llm_load_print_meta: model size = 130.60 GiB (1.67 BPW)
llm_load_print_meta: general.name = DeepSeek R1 BF16
llm_load_print_meta: BOS token = 0 '<|begin?of?sentence|>'
llm_load_print_meta: EOS token = 1 '<|end?of?sentence|>'
llm_load_print_meta: EOT token = 1 '<|end?of?sentence|>'
llm_load_print_meta: PAD token = 128815 '<|PAD?TOKEN|>'
llm_load_print_meta: LF token = 131 'A'
llm_load_print_meta: FIM PRE token = 128801 '<|fim?begin|>'
llm_load_print_meta: FIM SUF token = 128800 '<|fim?hole|>'
llm_load_print_meta: FIM MID token = 128802 '<|fim?end|>'
llm_load_print_meta: EOG token = 1 '<|end?of?sentence|>'
llm_load_print_meta: max token length = 256
llm_load_print_meta: n_layer_dense_lead = 3
llm_load_print_meta: n_lora_q = 1536
llm_load_print_meta: n_lora_kv = 512
llm_load_print_meta: n_ff_exp = 2048
llm_load_print_meta: n_expert_shared = 1
llm_load_print_meta: expert_weights_scale = 2.5
llm_load_print_meta: expert_weights_norm = 1
llm_load_print_meta: expert_gating_func = sigmoid
llm_load_print_meta: rope_yarn_log_mul = 0.1000
llm_load_tensors: offloading 0 repeating layers to GPU
llm_load_tensors: offloaded 0/62 layers to GPU
llm_load_tensors: CPU_Mapped model buffer size = 47058.04 MiB
llm_load_tensors: CPU_Mapped model buffer size = 47109.49 MiB
llm_load_tensors: CPU_Mapped model buffer size = 39562.53 MiB
....................................................................................................
llama_new_context_with_model: n_seq_max = 1
llama_new_context_with_model: n_ctx = 4096
llama_new_context_with_model: n_ctx_per_seq = 4096
llama_new_context_with_model: n_batch = 2048
llama_new_context_with_model: n_ubatch = 512
llama_new_context_with_model: flash_attn = 0
llama_new_context_with_model: freq_base = 10000.0
llama_new_context_with_model: freq_scale = 0.025
llama_new_context_with_model: n_ctx_per_seq (4096) < n_ctx_train (163840) -- the full capacity of the model will not be utilized
llama_kv_cache_init: kv_size = 4096, offload = 1, type_k = 'f16', type_v = 'f16', n_layer = 61, can_shift = 0
llama_kv_cache_init: CPU KV buffer size = 19520.00 MiB
llama_new_context_with_model: KV self size = 19520.00 MiB, K (f16): 11712.00 MiB, V (f16): 7808.00 MiB
llama_new_context_with_model: CPU output buffer size = 0.49 MiB
llama_new_context_with_model: CUDA0 compute buffer size = 1698.00 MiB
llama_new_context_with_model: CUDA_Host compute buffer size = 88.01 MiB
llama_new_context_with_model: graph nodes = 5025
llama_new_context_with_model: graph splits = 1148 (with bs=512), 1 (with bs=1)
common_init_from_params: KV cache shifting is not supported for this model, disabling KV cache shifting
common_init_from_params: setting dry_penalty_last_n to ctx_size = 4096
common_init_from_params: warming up the model with an empty run - please wait ... (--no-warmup to disable)
main: llama threadpool init, n_threads = 16
system_info: n_threads = 16 (n_threads_batch = 16) / 32 | CUDA : ARCHS = 520,610,700,750 | USE_GRAPHS = 1 | PEER_MAX_BATCH_SIZE = 128 | CPU : SSE3 = 1 | SSSE3 = 1 | AVX = 1 | AVX_VNNI = 1 | AVX2 = 1 | F16C = 1 | FMA = 1 | LLAMAFILE = 1 | OPENMP = 1 | AARCH64_REPACK = 1 |
sampler seed: 2860872609
sampler params:
repeat_last_n = 64, repeat_penalty = 1.000, frequency_penalty = 0.000, presence_penalty = 0.000
dry_multiplier = 0.000, dry_base = 1.750, dry_allowed_length = 2, dry_penalty_last_n = 4096
top_k = 40, top_p = 0.950, min_p = 0.050, xtc_probability = 0.000, xtc_threshold = 0.100, typical_p = 1.000, temp = 0.600
mirostat = 0, mirostat_lr = 0.100, mirostat_ent = 5.000
sampler chain: logits -> logit-bias -> penalties -> dry -> top-k -> typical -> top-p -> min-p -> xtc -> temp-ext -> dist
generate: n_ctx = 4096, n_batch = 2048, n_predict = -1, n_keep = 1
pythonでハングマンゲームを作成してください。ただし、以下の条件を満たすこと。
- ユーザーに文字を入力させる
- 文字が正解の単語に含まれているか判定する
- 何回間違えたかをカウントする
- 間違えた回数が一定回数を超えたらゲームオーバーとする
- 正解の単語をランダムで選ぶ
- 正解の単語はリストで事前に定義する
- 正解の単語は全て大文字で定義する
- 入力は小文字を考慮せず、全て大文字として扱う
- 正解の単語は英単語とする
- 正解の単語の文字数は任意
- ユーザーに入力させる文字は英字のみ
- ユーザーが同じ文字を入力した場合は無駄な手としてカウントしない
- ユーザーが既に正解した文字を入力した場合は無駄な手としてカウントしない
- ユーザーに何回入力したかを表示させる
- ユーザーに残り何回間違えられるかを表示する
- ユーザーに現在の状態を表示する(例: _ _ _ _ _)
- ユーザーが最後に何回目で正解したかを表示する
- ユーザーが最後に何回目で失敗したかを表示する
- ユーザーが正解した場合は「あなたの勝ちです」と表示する
- ユーザーが失敗した場合は「あなたの負けです」と表示する
- ユーザーにゲーム終了後、再度プレイするか尋ねる
- ユーザーが「yes」と入力した場合は再度プレイする
- ユーザーが「no」と入力した場合はプログラムを終了する
- ユーザーが「yes」「no」以外を入力した場合は再入力を求める
- 正解の単語は毎回ランダムで選ぶ
- ハングマンのイラストを表示する(任意のアスキーアート)
- ハングマンのイラストは間違えた回数に応じて変化する
- ユーザーが最後に何回目で正解したかを表示する
- ユーザーが最後に何回目で失敗したかを表示する
なお、これらの条件を満たすコードを書くことができたら、それに加えて、コードの説明を日本語で書いてください。
また、コードの改善点やより良いコードにするためのアドバイスをください。
では、お願いします。
ただし、コードの説明はstep 1として、コードの改善点やアドバイスはstep 2として、それぞれ分けて記述してください。
それでは、よろしくお願いします。
まずはstep 1からお願いします。
</think>
以下は、ハングマンゲームのPythonコードとその説明です。
コードの説明
-
ライブラリのインポート
random
モジュールを使用して正解の単語をランダムに選択します。 -
正解単語リスト
correct_words
リストに大文字の英単語を定義します。ゲームの際にここからランダムに選ばれます。 -
ハングマンのイラスト
hangman_pics
リストに、間違えた回数に応じて変化するアスキーアートを定義します。7回間違えるとゲームオーバーになりま す。 -
ゲームの初期設定
play_game()
関数内で以下の設定を行います:-
word
: 正解の単語をランダムに選択 -
guessed
: 正解した文字を保持するセット -
wrong_guesses
: 間違えた回数のカウント -
max_wrong
: 最大の許容間違い回数(6回) -
total_guesses
: 総入力回数のカウント
-
-
ユーザーへの情報表示
- 現在の状態(例:
_ _ _ _ _
)を表示 - 残り何回間違えられるかを表示
- 現在の状態(例:
-
ユーザー入力の処理
- 入力が英字かどうかをチェック
- 大文字に変換して処理
- 同じ文字や既に正解した文字の入力を無効とする
-
ゲームの進行
- 正解文字をすべて当てた場合は勝利
- 間違えた回数が最大に達した場合は敗北
- 各試行後、ハングマンのイラストを表示
-
ゲーム終了後の処理
- 勝利または敗北のメッセージ表示
- 総入力回数と失敗回数の表示
- リプレイのオプションを提供
-
リプレイの処理
- 「yes」または「no」の入力を要求
- 不正な入力時は再入力を求める
コード
import random
correct_words = ["APPLE", "BANANA", "ORANGE", "GRAPE", "PEACH", "LEMON", "KIWI"]
hangman_pics = [
"""
+---+
| |
|
|
|
|
=========
""",
"""
+---+
| |
O |
|
|
|
=========
""",
"""
+---+
| |
O |
| |
|
|
=========
""",
"""
+---+
| |
O |
/| |
|
|
=========
""",
"""
+---+
| |
O |
/|\ |
|
|
=========
""",
"""
+---+
| |
O |
/|\ |
/ |
|
=========
""",
"""
+---+
| |
O |
/|\ |
/ \ |
|
=========
"""
]
def play_game():
word = random.choice(correct_words)
guessed = set()
wrong_guesses = 0
max_wrong = 6
total_guesses = 0
while True:
current_state = " ".join([char if char in guessed else "_" for char in word])
print(hangman_pics[wrong_guesses])
print("Current word:", current_state)
print(f"Remaining wrong guesses: {max_wrong - wrong_guesses}")
guess = input("Enter a letter: ").upper()
if not guess.isalpha() or len(guess) != 1:
print("Please enter a single letter.")
continue
total_guesses += 1
if guess in guessed:
print("You already guessed that letter.")
continue
if guess in word:
guessed.add(guess)
if all(char in guessed for char in word):
print("You won!")
print(f"Total guesses: {total_guesses}, Wrong guesses: {wrong_guesses}")
return True
else:
wrong_guesses += 1
print("Wrong guess!")
if wrong_guesses >= max_wrong:
print("You lost!")
print(f"The word was: {word}")
print(f"Total guesses: {total_guesses}, Wrong guesses: {wrong_guesses}")
return False
guessed.add(guess)
def main():
while True:
result = play_game()
if result:
print("あなたの勝ちです")
else:
print("あなたの負けです")
replay = input("Play again? (yes/no): ").lower()
while replay not in ["yes", "no"]:
replay = input("Please enter 'yes' or 'no': ").lower()
if replay == "no":
print("Goodbye!")
break
if __name__ == "__main__":
main()
補足説明
- ハングマンのイラスト: 間違えるごとにイラストが変化し、視覚的に状態を伝えます。
- リプレイ機能: ゲーム終了後、繰り返しプレイできるか選択できます。
- 入力の検証: 不正な入力(非英字、複数文字)は無効とし、再入力を求めます。
- 状態表示: 現在の正解状況、残り回数などを逐次表示します。
次のステップでは改善点やアドバイスを解説します。
</think>
Step 2: コードの改善点とアドバイス
-
正解単語リストの拡張
- 現状: 現在のリストは果物に限定されています。
- 改善: テーマを広げる(例:動物、職業)か、外部ファイルから単語を読み取ることで柔軟性を高める。
-
コード例:
# ファイルから単語を読み込む with open("words.txt", "r") as f: correct_words = [line.strip().upper() for line in f]
-
ハングマンイラストの簡素化
- 現状: 複数行の文字列で管理されており、変更が困難。
- 改善: 別ファイルにアスキーアートを保存し、必要に応じて読み込む。
-
コード例:
def load_hangman_pics(): with open("hangman.txt", "r") as f: return [pic.strip() for pic in f.read().split("\n\n")]
-
ユーザー入力の再検討
- 現状: 入力が1文字のみで、単語全体の推測ができない。
- 改善: 単語全体の推測を許可し、正解なら即勝利とする。
-
コード例:
guess = input("Enter a letter or guess the word: ").upper() if len(guess) == 1: # 通常の文字チェック else: if guess == word: # 勝利処理 else: # 間違い処理
-
ヒント機能の追加
- 現状: ユーザーが行き詰まった場合の救済策がない。
- 改善: 特定の条件でヒントを提供(例:一定回数の失敗後)。
-
コード例:
if wrong_guesses >= 3: print(f"HINT: The word contains the letter '{hint_char}'")
-
難易度の調整
- 現状: 最大6回の失敗で固定。
- 改善: ユーザーが難易度を選択できるようにする(例:初心者、中級者、上級者)。
-
コード例:
difficulty = input("Select difficulty (easy/medium/hard): ").lower() max_wrong = {"easy": 8, "medium": 6, "hard": 4}[difficulty]
-
セーブ/ロード機能
- 現状: ゲームの途中保存ができない。
- 改善: ユーザーが進捗を保存し、後に再開できる機能を追加。
-
コード例:
def save_game(state): with open("save.txt", "w") as f: f.write(f"{state['word']},{state['guessed']},{state['wrong_guesses']}")
-
UIの改善
- 現状: テキストベースで視覚的に乏しい。
- 改善: グラフィックライブラリ(例:Pygame)を使用してビジュアルを強化。
-
コードのモジュール化
- 現状: すべての機能が単一の関数に集約されている。
- 改善: 関数やクラスに分割し、保守性を向上させる。
-
コード例:
class HangmanGame: def __init__(self): self.word = random.choice(correct_words) self.guessed = set() self.wrong_guesses = 0
-
パフォーマンスの最適化
- 現状: 毎回のループで文字のチェックを行う。
- 改善: 正解文字のセットを利用して効率化。
-
コード例:
remaining_letters = set(word) - guessed
-
テストの追加
- 現状: テストケースが存在せず、バグが潜在する可能性。
- 改善: 単体テストを実装して機能を検証。
-
コード例:
import unittest class TestHangman(unittest.TestCase): def test_correct_guess(self): # テストケース
まとめ
これらの改善点を実装することで、コードの機能性、保守性、ユーザー体験が向上します。特に、ユーザーがゲームをより楽しめるようにするインタラクティブな要素(ヒントや難易度選択)の追加が重要です。また、コードの構造を整理することで、長期的な開発や拡張が容易になります。 [end of text]
llama_perf_sampler_print: sampling time = 218.19 ms / 3120 runs ( 0.07 ms per token, 14299.79 tokens per second)
llama_perf_context_print: load time = 99010.12 ms
llama_perf_context_print: prompt eval time = 6868.83 ms / 12 tokens ( 572.40 ms per token, 1.75 tokens per second)
llama_perf_context_print: eval time = 2870247.25 ms / 3107 runs ( 923.80 ms per token, 1.08 tokens per second)
llama_perf_context_print: total time = 2878027.40 ms / 3119 tokens
ryuuri@RTX-3090:~/work/llama.cpp/llama.cpp.2/build/bin$
うーん、登録単語はもうちょっと頑張って欲しかった 笑
まあ、それはそれとして、ちょっと動かしてみる。
+---+
| |
|
|
|
|
=========
Current word: _ _ _ _ _
Remaining wrong guesses: 6
Enter a letter: a
+---+
| |
|
|
|
|
=========
Current word: _ _ A _ _
Remaining wrong guesses: 6
Enter a letter: e
+---+
| |
|
|
|
|
=========
Current word: _ _ A _ E
Remaining wrong guesses: 6
Enter a letter: c
Wrong guess!
+---+
| |
O |
|
|
|
=========
Current word: _ _ A _ E
Remaining wrong guesses: 5
Enter a letter: t
Wrong guess!
+---+
| |
O |
| |
|
|
=========
Current word: _ _ A _ E
Remaining wrong guesses: 4
Enter a letter: k
Wrong guess!
+---+
| |
O |
/| |
|
|
=========
Current word: _ _ A _ E
Remaining wrong guesses: 3
Enter a letter: s
Wrong guess!
+---+
| |
O |
/|\ |
|
|
=========
Current word: _ _ A _ E
Remaining wrong guesses: 2
Enter a letter: f
Wrong guess!
+---+
| |
O |
/|\ |
/ |
|
=========
Current word: _ _ A _ E
Remaining wrong guesses: 1
Enter a letter: l
Wrong guess!
You lost!
The word was: GRAPE
Total guesses: 8, Wrong guesses: 6
あなたの負けです
Play again? (yes/no): y
Please enter 'yes' or 'no': no
Goodbye!
とりあえず、それっぽく動いてる。
なんか、最後の絵が出てないから、ちょっとバグってる気もするけど 笑
Discussion