2505 A multiplication game

本文介绍了一个名为“乘法游戏”的简单博弈问题,通过玩家轮流将整数与2到9之间的数字相乘来决定胜负。文章提供了一段C++代码,用于判断在完美策略下哪位玩家能够首先达到或超过预先设定的阈值。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

A multiplication game
Time Limit: 1000MS Memory Limit: 65536K
Total Submissions: 3560 Accepted: 1669

Description

Stan and Ollie play the game of multiplication by multiplying an integer p by one of the numbers 2 to 9. Stan always starts with p = 1, does his multiplication, then Ollie multiplies the number, then Stan and so on. Before a game starts, they draw an integer 1 < n < 4294967295 and the winner is who first reaches p >= n.

Input

Each line of input contains one integer number n.

Output

For each line of input output one line either
Stan wins.
or
Ollie wins.
assuming that both of them play perfectly.

Sample Input

162
17
34012226

Sample Output

Stan wins.
Ollie wins.
Stan wins.
#include<iostream>
using namespace std;
int check(long long n)
{
    if(n<=18&&n>9) return 1;
    else if(n<=9&&n>1) return 0;
    if(n%9==0) n=n/9;
    else n=n/9+1;
    if(n%2==0) n=n/2;
    else n=n/2+1;
    return check(n);
}

int main()
{
    long long n;
    while(cin>>n)
    {
        if(check(n)==1)  cout<<"Ollie wins."<<endl;
        else cout<<"Stan wins."<<endl;
    }
    cout<<endl;
    return 0;
}
import os import sys import random import math import librosa import numpy as np from pygame import * import time as systime # ======================== # 游戏核心类定义 # ======================== class Ghost: def __init__(self): self.x = 200 self.y = 450 self.state = "neutral" # neutral, left, right, hit self.hit_timer = 0 self.speed = 5 def move(self, direction): """移动幽灵""" if direction == "left": self.x = max(50, self.x - self.speed) self.state = "left" elif direction == "right": self.x = min(1150, self.x + self.speed) self.state = "right" else: self.state = "neutral" def hit_effect(self): """击中效果""" self.state = "hit" self.hit_timer = 10 # 10帧的击中效果 def update(self): """更新幽灵状态""" if self.hit_timer > 0: self.hit_timer -= 1 if self.hit_timer == 0: self.state = "neutral" def get_rect(self): """获取幽灵碰撞矩形""" return Rect(self.x, self.y, 100, 100) class Note: def __init__(self, track, note_type, time_position, speed=5): """ 音符类 :param track: 轨道 (0=左轨, 1=右轨) :param note_type: 音符类型 (0=红/奇数, 1=蓝/偶数, 2=绿/质数, 3=黄/特殊) :param time_position: 音符出现的时间点(毫秒) :param speed: 移动速度(像素/帧) """ self.track = track self.note_type = note_type self.time_position = time_position self.speed = speed self.x = 1280 # 从屏幕右侧开始 self.y = 400 if track == 0 else 500 # 上下轨道位置 self.width = 50 self.height = 50 self.hit = False self.missed = False self.rect = Rect(self.x, self.y, self.width, self.height) def update(self): """更新音符位置""" self.x -= self.speed self.rect.x = self.x def draw(self, screen, note_images): """绘制音符""" if not self.hit and not self.missed: screen.blit(note_images[self.note_type], (self.x, self.y)) class MathProblem: def __init__(self, difficulty=1): """ 数学题目类 :param difficulty: 题目难度 (1-3) """ self.difficulty = difficulty self.generate_problem() self.time_limit = 10000 # 10秒答题时间 self.start_time = systime.time() * 1000 # 毫秒 def generate_problem(self): """生成数学题目""" problem_types = [ self.generate_addition, self.generate_subtraction, self.generate_multiplication, self.generate_division ] # 根据难度选择题目类型 if self.difficulty == 1: func = random.choice(problem_types[:2]) elif self.difficulty == 2: func = random.choice(problem_types) else: func = random.choice(problem_types[2:]) self.problem_text, self.correct_answer = func() def generate_addition(self): """生成加法题""" a = random.randint(1, 20) b = random.randint(1, 20) return f"{a} + {b} = ?", a + b def generate_subtraction(self): """生成减法题""" a = random.randint(10, 30) b = random.randint(1, a) return f"{a} - {b} = ?", a - b def generate_multiplication(self): """生成乘法题""" a = random.randint(1, 12) b = random.randint(1, 12) return f"{a} × {b} = ?", a * b def generate_division(self): """生成除法题""" b = random.randint(1, 10) a = b * random.randint(1, 10) return f"{a} ÷ {b} = ?", a // b def check_answer(self, answer): """检查答案是否正确""" return answer == self.correct_answer def is_prime(self, n): """检查数字是否为质数""" if n < 2: return False for i in range(2, int(math.sqrt(n)) + 1): if n % i == 0: return False return True def time_remaining(self): """返回剩余时间(毫秒)""" elapsed = systime.time() * 1000 - self.start_time return max(0, self.time_limit - elapsed) class RhythmGame: def __init__(self, screen, font_path=None): self.screen = screen self.font_path = font_path self.load_resources() self.reset_game() def load_resources(self): """加载游戏资源""" script_dir = os.path.dirname(os.path.abspath(__file__)) images_dir = os.path.join(script_dir, 'images') audio_dir = os.path.join(script_dir, 'audio') # 确保音频目录存在 if not os.path.exists(audio_dir): os.makedirs(audio_dir) print(f"已创建音频目录: {audio_dir}") # 加载图片 self.note_images = [ self.load_image(os.path.join(images_dir, "note_red.png")), self.load_image(os.path.join(images_dir, "note_blue.png")), self.load_image(os.path.join(images_dir, "note_green.png")), self.load_image(os.path.join(images_dir, "note_yellow.png")) ] self.pokey_images = { "left": self.load_image(os.path.join(images_dir, "pokey_left.png")), "right": self.load_image(os.path.join(images_dir, "pokey_right.png")), "neutral": self.load_image(os.path.join(images_dir, "pokey_neutral.png")), "hit": self.load_image(os.path.join(images_dir, "pokey_hit.png")) } self.track_bg = self.load_image(os.path.join(images_dir, "track_background.png")) self.judgment_line_img = self.load_image(os.path.join(images_dir, "judgment_line.png")) self.blackboard_img = self.load_image(os.path.join(images_dir, "blackboard.png")) self.combo_display_img = self.load_image(os.path.join(images_dir, "combo_display.png")) self.score_display_img = self.load_image(os.path.join(images_dir, "score_display.png")) self.health_bar_img = self.load_image(os.path.join(images_dir, "health_bar.png")) self.pause_button_img = self.load_image(os.path.join(images_dir, "pause_button.png")) # 加载字体 - 使用相对路径 try: # 使用指定的字体路径 if self.font_path and os.path.exists(self.font_path): self.font_large = font.Font(self.font_path, 48) self.font_medium = font.Font(self.font_path, 36) self.font_small = font.Font(self.font_path, 24) print(f"成功加载自定义字体: {self.font_path}") else: # 尝试加载默认字体 self.font_large = font.Font(None, 48) self.font_medium = font.Font(None, 36) self.font_small = font.Font(None, 24) print("使用系统默认字体") except: # 字体加载失败时使用回退方案 self.font_large = font.Font(None, 48) self.font_medium = font.Font(None, 36) self.font_small = font.Font(None, 24) print("字体加载失败,使用系统默认字体") # 加载音效 - 使用安全加载方法 self.sound_hit_perfect = self.load_sound(os.path.join(audio_dir, "hit_perfect.wav")) self.sound_hit_good = self.load_sound(os.path.join(audio_dir, "hit_good.wav")) self.sound_hit_miss = self.load_sound(os.path.join(audio_dir, "hit_miss.wav")) self.sound_combo_break = self.load_sound(os.path.join(audio_dir, "combo_break.wav")) self.sound_question = self.load_sound(os.path.join(audio_dir, "question_appear.wav")) self.sound_level_up = self.load_sound(os.path.join(audio_dir, "level_up.wav")) # 加载音乐 self.music_files = [ os.path.join(audio_dir, "song1.mp3"), os.path.join(audio_dir, "song2.mp3"), os.path.join(audio_dir, "song3.mp3") ] def load_image(self, path): """安全加载图片,如果失败则创建空表面""" try: if os.path.exists(path): return image.load(path).convert_alpha() else: print(f"图片文件不存在: {path}") except Exception as e: print(f"图片加载失败: {path}, 错误: {e}") # 创建空表面作为替代 return Surface((50, 50), SRCALPHA) def load_sound(self, path): """安全加载音效,如果失败则创建空音效""" try: if os.path.exists(path): return mixer.Sound(path) else: print(f"音效文件不存在: {path}") except Exception as e: print(f"音效加载失败: {path}, 错误: {e}") # 创建空音效作为替代 return mixer.Sound(buffer=bytes()) def reset_game(self): """重置游戏状态""" self.notes = [] self.current_problem = None self.score = 0 self.combo = 0 self.max_combo = 0 self.health = 100 self.song_index = 0 self.difficulty = 1 self.game_state = "playing" # playing, paused, game_over self.pokey = Ghost() self.load_song(self.music_files[self.song_index]) def load_song(self, file_path): """加载并分析歌曲""" # 检查文件是否存在 if not os.path.exists(file_path): print(f"音乐文件不存在: {file_path}") self.beat_times = [] return try: # 加载音频文件 mixer.music.load(file_path) # 使用librosa分析节拍 y, sr = librosa.load(file_path) tempo, beat_frames = librosa.beat.beat_track(y=y, sr=sr) # 将节拍点转换为毫秒 self.beat_times = librosa.frames_to_time(beat_frames, sr=sr) * 1000 # 生成音符 self.generate_notes() except Exception as e: print(f"歌曲加载失败: {e}") self.beat_times = [] def generate_notes(self): """根据节拍生成音符""" self.notes = [] for beat_time in self.beat_times: track = random.randint(0, 1) # 随机选择轨道 note_type = random.randint(0, 2) # 红、蓝、绿 # 20%几率生成特殊音符 if random.random() < 0.2: note_type = 3 # 黄色特殊音符 self.notes.append(Note(track, note_type, beat_time)) def start_math_problem(self): """开始一个新的数学问题""" self.current_problem = MathProblem(self.difficulty) try: self.sound_question.play() except: pass # 忽略音效播放错误 def check_note_hit(self, track, current_time): """ 检查音符是否击中 :param track: 玩家按下的轨道 :param current_time: 当前游戏时间(毫秒) """ perfect_threshold = 50 # 完美判定阈值(毫秒) good_threshold = 150 # 良好判定阈值(毫秒) for note in self.notes: if note.hit or note.missed: continue # 计算时间差 time_diff = abs(current_time - note.time_position) # 检查是否在判定范围内 if time_diff <= good_threshold and note.track == track: # 设置Pokey击中状态 self.pokey.hit_effect() # 检查是否与数学问题相关 if self.current_problem: answer_type = self.get_answer_type(self.current_problem.correct_answer) # 特殊音符总是正确的 if note.note_type == 3: # 黄色特殊音符 accuracy = "perfect" # 检查音符类型是否匹配答案类型 elif (note.note_type == 0 and answer_type == "odd") or \ (note.note_type == 1 and answer_type == "even") or \ (note.note_type == 2 and answer_type == "prime"): accuracy = "perfect" if time_diff <= perfect_threshold else "good" else: accuracy = "bad" else: accuracy = "perfect" if time_diff <= perfect_threshold else "good" # 处理击中结果 self.handle_hit_result(note, accuracy) return True return False def get_answer_type(self, answer): """获取答案的类型(奇数、偶数、质数)""" if answer % 2 == 0: return "even" elif self.current_problem.is_prime(answer): return "prime" else: return "odd" def handle_hit_result(self, note, accuracy): """处理击中结果""" note.hit = True if accuracy == "perfect": self.score += 100 * self.combo_multiplier() self.combo += 1 try: self.sound_hit_perfect.play() except: pass elif accuracy == "good": self.score += 50 * self.combo_multiplier() self.combo += 1 try: self.sound_hit_good.play() except: pass else: # bad self.health -= 5 self.break_combo() try: self.sound_hit_miss.play() except: pass self.max_combo = max(self.max_combo, self.combo) def break_combo(self): """中断连击""" if self.combo >= 5: try: self.sound_combo_break.play() except: pass self.combo = 0 def combo_multiplier(self): """计算连击倍数""" if self.combo < 5: return 1 elif self.combo < 10: return 1.2 elif self.combo < 20: return 1.5 else: return 2.0 def update(self, current_time): """更新游戏状态""" if self.game_state != "playing": return # 更新Pokey状态 self.pokey.update() # 更新音符 for note in self.notes: note.update() # 检查是否错过音符 if not note.hit and not note.missed and note.x < 200: note.missed = True self.health -= 2 self.break_combo() try: self.sound_hit_miss.play() except: pass # 检查是否需要新题目 if not self.current_problem or self.current_problem.time_remaining() <= 0: self.start_math_problem() # 检查游戏结束 if self.health <= 0: self.game_state = "game_over" def draw(self): """绘制游戏界面""" # 绘制背景 self.screen.blit(self.track_bg, (0, 0)) # 绘制判定线 self.screen.blit(self.judgment_line_img, (250, 300)) # 绘制音符 for note in self.notes: note.draw(self.screen, self.note_images) # 绘制Pokey pokey_img = self.pokey_images[self.pokey.state] self.screen.blit(pokey_img, (self.pokey.x, self.pokey.y)) # 绘制黑板和题目 if self.current_problem: self.screen.blit(self.blackboard_img, (400, 100)) problem_text = self.font_large.render(self.current_problem.problem_text, True, (255, 255, 255)) self.screen.blit(problem_text, (450, 150)) # 绘制剩余时间条 time_remaining = self.current_problem.time_remaining() / self.current_problem.time_limit time_bar_width = int(300 * time_remaining) draw.rect(self.screen, (0, 255, 0), (450, 200, time_bar_width, 20)) # 绘制UI元素 self.screen.blit(self.score_display_img, (20, 20)) score_text = self.font_medium.render(f"Score: {self.score}", True, (255, 255, 255)) self.screen.blit(score_text, (40, 30)) self.screen.blit(self.combo_display_img, (20, 70)) combo_text = self.font_medium.render(f"Combo: {self.combo}x", True, (255, 255, 255)) self.screen.blit(combo_text, (40, 80)) self.screen.blit(self.health_bar_img, (1100, 20)) health_width = int(150 * (self.health / 100)) draw.rect(self.screen, (255, 0, 0), (1105, 25, health_width, 20)) self.screen.blit(self.pause_button_img, (1200, 650)) # 游戏结束画面 if self.game_state == "game_over": overlay = Surface((1280, 720), SRCALPHA) overlay.fill((0, 0, 0, 180)) self.screen.blit(overlay, (0, 0)) game_over_text = self.font_large.render("Game Over", True, (255, 0, 0)) score_text = self.font_medium.render(f"Final Score: {self.score}", True, (255, 255, 255)) combo_text = self.font_medium.render(f"Max Combo: {self.max_combo}", True, (255, 255, 255)) restart_text = self.font_medium.render("Press R to restart", True, (255, 255, 255)) self.screen.blit(game_over_text, (540, 300)) self.screen.blit(score_text, (540, 370)) self.screen.blit(combo_text, (540, 410)) self.screen.blit(restart_text, (540, 470)) # 暂停画面 elif self.game_state == "paused": overlay = Surface((1280, 720), SRCALPHA) overlay.fill((0, 0, 0, 180)) self.screen.blit(overlay, (0, 0)) pause_text = self.font_large.render("Game Paused", True, (255, 255, 0)) continue_text = self.font_medium.render("Press P to continue", True, (255, 255, 255)) self.screen.blit(pause_text, (520, 300)) self.screen.blit(continue_text, (520, 370)) # ======================== # 游戏主程序 # ======================== def Mam_draw_map(screen, show_buttons, bar_height, background_offset, conversation_mode, current_conversation_img, text_line1, text_line2, text_progress, font): """绘制游戏场景(优化显示更新)""" color = (192,192,192) screen.fill(color) if not conversation_mode: # 滚动模式:绘制背景和对话图片 screen.blit(background, (background_offset, -200)) screen.blit(conversation_1, (background_offset + background.get_width(), -200)) # 如果需要,在更右侧绘制第二张背景以保持连续性 if background_offset < 0: screen.blit(background, (background_offset + 2 * background.get_width(), -200)) else: # 对话模式:绘制当前对话图片 screen.blit(current_conversation_img, (0, -200)) # 根据show_buttons标志决定是否绘制标题和按钮 if show_buttons: screen.blit(title_img, (0, 0)) screen.blit(button_start_img, (500, 500)) screen.blit(button_quit_img, (500, 570)) # 绘制上下黑条(始终绘制) if bar_height > 0: # 上黑条 draw.rect(screen, (0, 0, 0), (0, 0, screen.get_width(), bar_height)) # 下黑条 draw.rect(screen, (0, 0, 0), (0, screen.get_height() - bar_height, screen.get_width(), bar_height)) # 在对话模式下绘制文本 if conversation_mode and text_progress > 0 and font: # 创建半透明背景 text_bg = Surface((screen.get_width(), bar_height * 2), SRCALPHA) text_bg.fill((0, 0, 0, 200)) # 半透明黑色 # 绘制文本背景 screen.blit(text_bg, (0, (screen.get_height() - bar_height * 2) // 2)) # 绘制第一行文本 if text_progress >= 1: text_surface1 = font.render(text_line1, True, (255, 255, 255)) text_rect1 = text_surface1.get_rect(center=(screen.get_width() // 2, screen.get_height() // 2 - 30)) screen.blit(text_surface1, text_rect1) # 绘制第二行文本 if text_progress >= 2: text_surface2 = font.render(text_line2, True, (255, 255, 255)) text_rect2 = text_surface2.get_rect(center=(screen.get_width() // 2, screen.get_height() // 2 + 30)) screen.blit(text_surface2, text_rect2) # 使用更高效的显示更新方式 display.flip() def main(): # 初始化pygame init() screen = display.set_mode((1280, 720)) display.set_caption("数学节奏大师: Pokey的冒险") clock = time.Clock() # 获取当前脚本所在目录 script_dir = os.path.dirname(os.path.abspath(__file__)) images_dir = os.path.join(script_dir, 'images') fonts_dir = os.path.join(script_dir, 'fonts') # 字体文件夹路径 audio_dir = os.path.join(script_dir, 'audio') # 音频文件夹路径 # 确保图片目录存在 if not os.path.exists(images_dir): os.makedirs(images_dir) print(f"已创建图片目录: {images_dir}") # 确保字体目录存在 if not os.path.exists(fonts_dir): os.makedirs(fonts_dir) print(f"已创建字体目录: {fonts_dir}") # 确保音频目录存在 if not os.path.exists(audio_dir): os.makedirs(audio_dir) print(f"已创建音频目录: {audio_dir}") # 字体文件路径 font_file = "HYPixel11pxU-2.ttf" font_path = os.path.join(fonts_dir, font_file) # 加载游戏字体 try: # 尝试加载指定字体 game_font = font.Font(font_path, 48) print(f"成功加载字体: {font_path}") except: # 字体加载失败时使用系统默认字体 try: game_font = font.Font(None, 48) print("使用系统默认字体") except: print("警告:无法加载任何字体,文本将无法显示") game_font = None # 加载游戏图片资源 def safe_load_image(path, default_size=(50, 50)): """安全加载图片,如果失败则创建空表面""" try: if os.path.exists(path): return image.load(path).convert_alpha() else: print(f"图片文件不存在: {path}") except Exception as e: print(f"图片加载失败: {path}, 错误: {e}") # 创建空表面作为替代 return Surface(default_size, SRCALPHA) try: background = safe_load_image(os.path.join(images_dir, 'background.png'), (1280, 720)) button_start_img = safe_load_image(os.path.join(images_dir, 'button_start.png')) button_quit_img = safe_load_image(os.path.join(images_dir, 'button_quit.png')) title_img = safe_load_image(os.path.join(images_dir, 'title.png')) conversation_1 = safe_load_image(os.path.join(images_dir, 'conversation_1.png')) conversation_2 = safe_load_image(os.path.join(images_dir, 'conversation_2.png')) print("图片加载完成(部分可能使用替代图像)") except Exception as e: print(f"图片加载过程中发生错误: {e}") quit() sys.exit(1) # 游戏状态变量 game_state = "menu" # menu, story, rhythm_game show_buttons = True bar_height = 0 target_bar_height = screen.get_height() // 6 background_offset = 0 target_background_offset = -background.get_width() animation_speed = 5 animation_active = False conversation_mode = False current_conversation_img = conversation_1 last_switch_time = systime.time() switch_interval = 0.5 text_line1 = "『你不该来这里的。』" text_line2 = "『抱歉,朋友。我也没得选择。』" text_progress = 0 last_text_time = 0 # 创建按钮矩形区域 start_button_rect = button_start_img.get_rect(topleft=(500, 500)) quit_button_rect = button_quit_img.get_rect(topleft=(500, 570)) # 初始化节奏游戏,传入字体路径 rhythm_game = RhythmGame(screen, font_path) running = True while running: current_time = systime.time() clock.tick(60) for event in pygame.event.get(): if event.type == QUIT: running = False if game_state == "menu": if event.type == MOUSEBUTTONDOWN: mouse_pos = mouse.get_pos() if show_buttons: if start_button_rect.collidepoint(mouse_pos): show_buttons = False animation_active = True print("开始游戏!") elif quit_button_rect.collidepoint(mouse_pos): running = False print("退出游戏") elif game_state == "story": if event.type == MOUSEBUTTONDOWN: if conversation_mode and text_progress < 2: text_progress += 1 elif game_state == "rhythm_game": if event.type == KEYDOWN: if event.key == K_LEFT: rhythm_game.check_note_hit(0, current_time * 1000) elif event.key == K_RIGHT: rhythm_game.check_note_hit(1, current_time * 1000) elif event.key == K_p: if rhythm_game.game_state == "playing": rhythm_game.game_state = "paused" mixer.music.pause() elif rhythm_game.game_state == "paused": rhythm_game.game_state = "playing" mixer.music.unpause() elif event.key == K_r and rhythm_game.game_state == "game_over": rhythm_game.reset_game() mixer.music.play() elif event.key == K_ESCAPE: game_state = "menu" rhythm_game.reset_game() if event.type == MOUSEBUTTONDOWN: mouse_pos = pygame.mouse.get_pos() if rhythm_game.game_state == "playing" and 1200 <= mouse_pos[0] <= 1260 and 650 <= mouse_pos[1] <= 710: rhythm_game.game_state = "paused" mixer.music.pause() # 更新游戏状态 if game_state == "menu": # 更新动画 if animation_active: # 更新黑条高度 if bar_height < target_bar_height: bar_height += animation_speed if bar_height > target_bar_height: bar_height = target_bar_height # 更新背景滚动位置 if background_offset > target_background_offset: background_offset -= animation_speed if background_offset < target_background_offset: background_offset = target_background_offset # 检查动画是否完成 if bar_height == target_bar_height and background_offset == target_background_offset: animation_active = False conversation_mode = True last_text_time = current_time print("进入对话模式") # 对话模式 if conversation_mode: # 图片切换 if current_time - last_switch_time > switch_interval: if current_conversation_img == conversation_1: current_conversation_img = conversation_2 else: current_conversation_img = conversation_1 last_switch_time = current_time # 文本显示进度 if text_progress == 0 and current_time - last_text_time > 1.0: text_progress = 1 last_text_time = current_time elif text_progress == 1 and current_time - last_text_time > 3.0: text_progress = 2 last_text_time = current_time # 文本显示完成后进入节奏游戏 game_state = "rhythm_game" try: mixer.music.play() except: print("音乐播放失败,游戏继续运行") # 绘制菜单/故事场景 Mam_draw_map(screen, show_buttons, bar_height, background_offset, conversation_mode, current_conversation_img, text_line1, text_line2, text_progress, game_font) elif game_state == "rhythm_game": # 更新节奏游戏 rhythm_game.update(current_time * 1000) rhythm_game.draw() display.flip() quit() if __name__ == "__main__": main() 分析这段代码所有可能导致游戏无法运行的bug
最新发布
07-23
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值