基于opensees+activateTcl实现一个记忆配对游戏

张开发
2026/4/14 20:04:50 15 分钟阅读

分享文章

基于opensees+activateTcl实现一个记忆配对游戏
这个记忆配对游戏的玩法很简单让我为您详细说明 游戏规则游戏目标找出所有配对的数字卡片基本玩法游戏开始时所有卡片都是背面朝上蓝色点击卡片会翻转显示数字每次点击两张卡片比较数字是否相同如果数字相同配对成功卡片保持翻开状态如果数字不同配对失败卡片会自动翻回背面胜利条件将所有卡片都成功配对 游戏特点三种难度选择简单4×4 网格8对卡片中等4×6 网格12对卡片困难6×6 网格18对卡片统计信息移动次数记录您翻转卡片的次数配对数量显示已成功配对的数量计时器记录完成游戏所用的时间 游戏技巧记忆策略记住已翻转卡片的位置和数字尝试在脑中建立“数字→位置”的映射优先配对已知位置的相同数字系统方法按顺序逐行翻转卡片先找出所有数字的位置再集中进行配对提高效率观察已配对卡片的分布利用排除法缩小搜索范围保持专注避免重复翻转同一张卡片 操作说明点击卡片翻转查看数字新游戏按钮重新开始当前难度的游戏主菜单按钮返回难度选择界面退出游戏关闭程序 游戏界面说明┌─────────────────────────────────┐ │ 移动次数: 0 配对: 0/8 时间: 0秒 │ ← 统计栏 ├─────────────────────────────────┤ │ [1] [2] [3] [4] │ │ [5] [6] [7] [8] │ ← 游戏板 │ [1] [3] [5] [7] │ │ [2] [4] [6] [8] │ ├─────────────────────────────────┤ │ [新游戏] [主菜单] │ ← 控制按钮 └─────────────────────────────────┘ 游戏示例假设您看到第1行第1列显示数字5第3行第2列也显示数字5那么这两张卡片就是一对配对成功⭐ 小贴士不要着急游戏没有时间限制只有计时记录配对失败时卡片会停留1秒后翻回利用这段时间记忆位置越难的关卡越考验记忆力可以先从简单模式开始练习这个游戏主要锻炼短期记忆能力和注意力集中通过不断练习可以显著提升记忆力祝您游戏愉快测试环境opensees3.7.1activateTcl8.6.11源码#!/usr/bin/env wish package require Tk # 全局变量 setGAME(rows)4setGAME(cols)4setGAME(totalPairs)0setGAME(firstRow)-1setGAME(firstCol)-1setGAME(secondRow)-1setGAME(secondCol)-1setGAME(canFlip)1setGAME(moves)0setGAME(matches)0setGAME(timeElapsed)0setGAME(timerId)setGAME(gameActive)0# 初始化游戏 proc initGame{rows cols}{global GAME setGAME(rows)$rows setGAME(cols)$cols setGAME(totalPairs)[expr{$rows*$cols/2}]setGAME(firstRow)-1setGAME(firstCol)-1setGAME(secondRow)-1setGAME(secondCol)-1setGAME(canFlip)1setGAME(moves)0setGAME(matches)0setGAME(timeElapsed)0setGAME(gameActive)1# 停止旧计时器if{$GAME(timerId)!}{after cancel $GAME(timerId)setGAME(timerId)}# 创建卡片内容 set symbols{}for{set i1}{$i$GAME(totalPairs)}{incr i}{lappend symbols $i $i}# 随机打乱for{set i0}{$i[llength $symbols]}{incr i}{set j[expr{int(rand()*[llength $symbols])}]set temp[lindex $symbols $i]set symbols[lreplace $symbols $i $i[lindex $symbols $j]]set symbols[lreplace $symbols $j $j $temp]}# 存储卡片值for{set i0}{$i$rows}{incr i}{for{set j0}{$j$cols}{incr j}{set index[expr{$i*$cols$j}]setGAME(card_${i}_${j})[lindex $symbols $index]setGAME(flipped_${i}_${j})0setGAME(matched_${i}_${j})0}}# 清除主窗口内容转换为游戏界面 clearMainWindow drawGameBoard}# 清除主窗口内容 proc clearMainWindow{}{# 删除所有子控件 foreach child[winfo children.]{destroy $child}# 重置窗口标题和协议 wm title.记忆配对游戏wm protocol.WM_DELETE_WINDOW{exitGame}# 设置背景色.configure-bg lightgray}# 开始计时 proc startTimer{}{global GAMEif{$GAME(gameActive)}{incrGAME(timeElapsed)if{[winfo exists.stats.time]}{.stats.time configure-text时间: $GAME(timeElapsed)秒}setGAME(timerId)[after1000startTimer]}}# 绘制游戏板 proc drawGameBoard{}{global GAME # 状态栏 frame.stats-relief raised-bd2-bg lightgray pack.stats-fill x-pady5label.stats.moves-text移动次数: 0-font{Arial12bold}-bg lightgray pack.stats.moves-side left-padx20-pady5label.stats.pairs-text配对: 0/$GAME(totalPairs)-font{Arial12bold}-bg lightgray pack.stats.pairs-side left-padx20-pady5label.stats.time-text时间: 0秒-font{Arial12bold}-bg lightgray pack.stats.time-side left-padx20-pady5button.stats.reset-text新游戏-command resetGame-font{Arial10bold}-bg lightblue pack.stats.reset-side right-padx20-pady5button.stats.menu-text主菜单-command returnToMenu-font{Arial10bold}-bg lightgreen pack.stats.menu-side right-padx5-pady5# 游戏板 frame.board-bg gray pack.board-expand1-fill both-padx10-pady10# 创建卡片for{set i0}{$i$GAME(rows)}{incr i}{for{set j0}{$j$GAME(cols)}{incr j}{button.board.btn_${i}_${j}-text-width8-height4\-font{Arial20bold}-bg lightblue-activebackground skyblue \-command[list flipCard $i $j]grid.board.btn_${i}_${j}-row $i-column $j-padx2-pady2-sticky nsew}}# 配置网格for{set i0}{$i$GAME(rows)}{incr i}{grid rowconfigure.board $i-weight1}for{set j0}{$j$GAME(cols)}{incr j}{grid columnconfigure.board $j-weight1}# 启动计时器 startTimer}# 翻转卡片 proc flipCard{row col}{global GAMEif{!$GAME(gameActive)}returnif{!$GAME(canFlip)}returnif{$GAME(flipped_${row}_${col})}returnif{$GAME(matched_${row}_${col})}return# 显示卡片 set btn.board.btn_${row}_${col}$btn configure-text $GAME(card_${row}_${col})-bg yellow-state disabled setGAME(flipped_${row}_${col})1# 第一张卡片if{$GAME(firstRow)-1}{setGAME(firstRow)$row setGAME(firstCol)$colreturn}# 第二张卡片if{$GAME(secondRow)-1}{setGAME(secondRow)$row setGAME(secondCol)$col incrGAME(moves)updateStats # 检查匹配 set firstVal $GAME(card_${GAME(firstRow)}_${GAME(firstCol)})set secondVal $GAME(card_${row}_${col})if{$firstVal$secondVal}{# 匹配成功 setGAME(matched_${GAME(firstRow)}_${GAME(firstCol)})1setGAME(matched_${row}_${col})1incrGAME(matches)updateStats setGAME(firstRow)-1setGAME(firstCol)-1setGAME(secondRow)-1setGAME(secondCol)-1# 检查胜利if{$GAME(matches)$GAME(totalPairs)}{gameWin}}else{# 匹配失败 setGAME(canFlip)0after1000resetFlip}}}# 重置翻转匹配失败时 proc resetFlip{}{global GAMEif{!$GAME(gameActive)}return# 翻回第一张if{$GAME(firstRow)!-1!$GAME(matched_${GAME(firstRow)}_${GAME(firstCol)})}{set btn1.board.btn_${GAME(firstRow)}_${GAME(firstCol)}if{[winfo exists $btn1]}{$btn1 configure-text-bg lightblue-state normal}setGAME(flipped_${GAME(firstRow)}_${GAME(firstCol)})0}# 翻回第二张if{$GAME(secondRow)!-1!$GAME(matched_${GAME(secondRow)}_${GAME(secondCol)})}{set btn2.board.btn_${GAME(secondRow)}_${GAME(secondCol)}if{[winfo exists $btn2]}{$btn2 configure-text-bg lightblue-state normal}setGAME(flipped_${GAME(secondRow)}_${GAME(secondCol)})0}setGAME(firstRow)-1setGAME(firstCol)-1setGAME(secondRow)-1setGAME(secondCol)-1setGAME(canFlip)1}# 更新统计 proc updateStats{}{global GAMEif{[winfo exists.stats.moves]}{.stats.moves configure-text移动次数: $GAME(moves).stats.pairs configure-text配对: $GAME(matches)/$GAME(totalPairs)}}# 游戏胜利 proc gameWin{}{global GAME setGAME(gameActive)0if{$GAME(timerId)!}{after cancel $GAME(timerId)setGAME(timerId)}tk_messageBox-title恭喜胜利\-message 恭喜你赢了 \n\n移动次数: $GAME(moves)\n用时: $GAME(timeElapsed)秒\-type ok-icon info set playAgain[tk_messageBox-title新游戏-message是否开始新游戏-type yesno]if{$playAgainyes}{resetGame}else{returnToMenu}}# 重置游戏 proc resetGame{}{global GAMEif{$GAME(timerId)!}{after cancel $GAME(timerId)setGAME(timerId)}initGame $GAME(rows)$GAME(cols)}# 返回主菜单 proc returnToMenu{}{global GAME # 停止计时器if{$GAME(timerId)!}{after cancel $GAME(timerId)setGAME(timerId)}# 清除游戏界面显示主菜单 clearMainWindow showMenu}# 退出游戏 proc exitGame{}{global GAMEif{$GAME(timerId)!}{after cancel $GAME(timerId)}# 询问是否退出 set confirm[tk_messageBox-title退出-message确定要退出游戏吗-type yesno-icon question]if{$confirmyes}{exit}}# 显示主菜单 proc showMenu{}{# 初始化随机数 expr{srand([clock seconds])}# 设置主窗口 wm title.记忆配对游戏wm geometry.400x400wm protocol.WM_DELETE_WINDOW{exitGame}.configure-bg lightgray label.title-text 记忆配对游戏 -font{Arial22bold}\-fg blue-bg lightgray pack.title-pady30label.info-text选择游戏难度-font{Arial14bold}-bg lightgray pack.info-pady10button.easy-text简单 (4x4)-font{Arial12bold}-bg lightgreen \-command{initGame44}-width15-height2pack.easy-pady5button.medium-text中等 (4x6)-font{Arial12bold}-bg yellow \-command{initGame46}-width15-height2pack.medium-pady5button.hard-text困难 (6x6)-font{Arial12bold}-bg lightcoral \-command{initGame66}-width15-height2pack.hard-pady5label.rules-text 规则点击卡片找出所有相同的数字对\-font{Arial10}-fg gray-bg lightgray pack.rules-pady15button.exit-text退出游戏-font{Arial11bold}-bg lightgray \-command exitGame-width12-height1pack.exit-pady10}# 启动游戏-直接显示主菜单 showMenu运行效果将上面代码保存为test.tcl注意需要是ANSI格式然后双击运行

更多文章