C#游戏开发的实例
以下是一些C#游戏开发的实例,涵盖不同难度和类型,适合从入门到进阶的学习参考。这些例子可以通过Unity、MonoGame或其他C#游戏框架实现。
猜数字游戏
基础版猜数字游戏
使用Random
类生成1-100的随机数,玩家通过控制台输入猜测,程序提示“太大”或“太小”,直到猜中后显示尝试次数。
using System;
class GuessNumber
{
static void Main()
{
Random random = new Random();
int target = random.Next(1, 101);
int guess, attempts = 0;
Console.WriteLine("猜数字游戏(1-100)");
do
{
Console.Write("输入你的猜测: ");
guess = int.Parse(Console.ReadLine());
attempts++;
if (guess > target) Console.WriteLine("太大");
else if (guess < target) Console.WriteLine("太小");
} while (guess != target);
Console.WriteLine($"恭喜!猜中数字 {target},共尝试 {attempts} 次");
}
}
进阶版猜数字游戏
添加输入验证、次数限制(10次)和重玩功能,使用TryParse
处理非法输入。
using System;
class AdvancedGuessNumber
{
static void Main()
{
bool playAgain = true;
while (playAgain)
{
Random random = new Random();
int target = random.Next(1, 101);
int guess, attempts = 0, maxAttempts = 10;
Console.WriteLine($"猜数字游戏(1-100),最多{maxAttempts}次尝试");
while (attempts < maxAttempts)
{
Console.Write($"剩余尝试次数 {maxAttempts - attempts}: ");
if (!int.TryParse(Console.ReadLine(), out guess))
{
Console.WriteLine("请输入有效数字");
continue;
}
attempts++;
if (guess == target)
{
Console.WriteLine($"恭喜!第{attempts}次猜中数字 {target}");
break;
}
Console.WriteLine(guess > target ? "太大" : "太小");
}
if (attempts >= maxAttempts)
Console.WriteLine($"失败!正确数字是 {target}");
Console.Write("再玩一次?(y/n): ");
playAgain = Console.ReadLine().ToLower() == "y";
}
}
}
关键实现说明
- 随机数生成:
Random.Next(minValue, maxValue)
包含下限不包含上限 - 输入验证:
int.TryParse
避免程序因非法输入崩溃 - 循环控制:
do-while
确保至少执行一次,while
配合计数器限制尝试次数
两个版本均可在Visual Studio或.NET CLI中直接运行,进阶版通过增加异常处理和游戏流程控制提升用户体验。
井字棋(Tic-Tac-Toe)
简易控制台井字棋
以下是一个基础的C#控制台井字棋实现,包含玩家轮流输入坐标的功能:
using System;
class TicTacToe
{
static char[] board = { '1', '2', '3', '4', '5', '6', '7', '8', '9' };
static int currentPlayer = 1;
static void Main()
{
int choice;
bool validInput;
int gameStatus = 0; // 0:游戏继续, 1:有赢家, -1:平局
do
{
Console.Clear();
Console.WriteLine("玩家1: X 和 玩家2: O");
Console.WriteLine("\n");
DrawBoard();
Console.WriteLine($"玩家 {currentPlayer} 的回合,输入位置数字:");
validInput = int.TryParse(Console.ReadLine(), out choice);
if (validInput && choice >= 1 && choice <= 9 && board[choice - 1] != 'X' && board[choice - 1] != 'O')
{
board[choice - 1] = (currentPlayer == 1) ? 'X' : 'O';
currentPlayer = (currentPlayer == 1) ? 2 : 1;
}
gameStatus = CheckWin();
}
while (gameStatus == 0);
Console.Clear();
DrawBoard();
if (gameStatus == 1)
Console.WriteLine($"玩家 {(currentPlayer == 1 ? 2 : 1)} 获胜!");
else
Console.WriteLine("平局!");
}
static void DrawBoard()
{
Console.WriteLine($" {board[0]} | {board[1]} | {board[2]} ");
Console.WriteLine("-----------");
Console.WriteLine($" {board[3]} | {board[4]} | {board[5]} ");
Console.WriteLine("-----------");
Console.WriteLine($" {board[6]} | {board[7]} | {board[8]} ");
}
static int CheckWin()
{
// 检查行
for (int i = 0; i < 9; i += 3)
if (board[i] == board[i + 1] && board[i + 1] == board[i + 2])
return 1;
// 检查列
for (int i = 0; i < 3; i++)
if (board[i] == board[i + 3] && board[i + 3] == board[i + 6])
return 1;
// 检查对角线
if ((board[0] == board[4] && board[4] == board[8]) ||
(board[2] == board[4] && board[4] == board[6]))
return 1;
// 检查平局
foreach (char spot in board)
if (spot != 'X' && spot != 'O')
return 0;
return -1;
}
}
面向对象版本
这个版本使用面向对象设计,分离了游戏逻辑和显示逻辑:
public class TicTacToeGame
{
private char[] board;
private int currentPlayer;
public TicTacToeGame()
{
board = new char[] { '1', '2', '3', '4', '5', '6', '7', '8', '9' };
currentPlayer = 1;
}
public bool MakeMove(int position)
{
if (position < 1 || position > 9 || board[position - 1] == 'X' || board[position - 1] == 'O')
return false;
board[position - 1] = (currentPlayer == 1) ? 'X' : 'O';
currentPlayer = 3 - currentPlayer; // 在1和2之间切换
return true;
}
public int CheckGameStatus()
{
// 检查行
for (int i = 0; i < 9; i += 3)
if (board[i] != ' ' && board[i] == board[i + 1] && board[i + 1] == board[i + 2])
return board[i] == 'X' ? 1 : 2;
// 检查列
for (int i = 0; i < 3; i++)
if (board[i] != ' ' && board[i] == board[i + 3] && board[i + 3] == board[i + 6])
return board[i] == 'X' ? 1 : 2;
// 检查对角线
if (board[0] != ' ' && board[0] == board[4] && board[4] == board[8])
return board[0] == 'X' ? 1 : 2;
if (board[2] != ' ' && board[2] == board[4] && board[4] == board[6])
return board[2] == 'X' ? 1 : 2;
// 检查平局
foreach (char spot in board)
if (spot != 'X' && spot != 'O')
return 0; // 游戏继续
return -1; // 平局
}
public char[] GetBoardState() => (char[])board.Clone();
public int GetCurrentPlayer() => currentPlayer;
}
WPF图形界面版本
以下是WPF实现的图形界面井字棋核心代码:
public partial class MainWindow : Window
{
private TicTacToeGame game = new TicTacToeGame();
private Button[] buttons;
public MainWindow()
{
InitializeComponent();
buttons = new Button[] { btn1, btn2, btn3, btn4, btn5, btn6, btn7, btn8, btn9 };
}
private void Button_Click(object sender, RoutedEventArgs e)
{
Button button = (Button)sender;
int position = int.Parse(button.Tag.ToString());
if (game.MakeMove(position))
{
button.Content = game.GetBoardState()[position - 1];
button.IsEnabled = false;
int status = game.CheckGameStatus();
if (status > 0)
MessageBox.Show($"玩家 {status} 获胜!");
else if (status == -1)
MessageBox.Show("平局!");
}
}
private void NewGame_Click(object sender, RoutedEventArgs e)
{
game = new TicTacToeGame();
foreach (Button btn in buttons)
{
btn.Content = "";
btn.IsEnabled = true;
}
}
}
简单AI对手
添加一个随机选择空位的简单AI:
public class TicTacToeAI
{
private Random random = new Random();
public int GetAIMove(char[] board)
{
List<int> availableMoves = new List<int>();
for (int i = 0; i < 9; i++)
if (board[i] != 'X' && board[i] != 'O')
availableMoves.Add(i + 1);
return availableMoves.Count > 0 ?
availableMoves[random.Next(availableMoves.Count)] : -1;
}
}
// 使用示例
TicTacToeAI ai = new TicTacToeAI();
int aiMove = ai.GetAIMove(game.GetBoardState());
if (aiMove != -1)
game.MakeMove(aiMove);
最小最大算法AI
实现一个使用最小最大算法的不败AI:
public class MinimaxAI
{
public int GetBestMove(char[] board, char player)
{
int bestScore = int.MinValue;
int bestMove = -1;
for (int i = 0; i < 9; i++)
{
if (board[i] != 'X' && board[i] != 'O')
{
board[i] = player;
int score = Minimax(board, 0, false, player);
board[i] = (i + 1).ToString()[0]; // 撤销移动
if (score > bestScore)
{
bestScore = score;
bestMove = i + 1;
}
}
}
return bestMove;
}
private int Minimax(char[] board, int depth, bool isMaximizing, char player)
{
char opponent = (player == 'X') ? 'O' : 'X';
int result = Evaluate(board, player);
if (result != 0) return result;
if (IsBoardFull(board)) return 0;
if (isMaximizing)
{
int bestScore = int.MinValue;
for (int i = 0; i < 9; i++)
{
if (board[i] != 'X' && board[i] != 'O')
{
board[i] = player;
int score = Minimax(board, depth + 1, false, player);
board[i] = (i + 1).ToString()[0];
bestScore = Math.Max(score, bestScore);
}
}
return bestScore;
}
else
{
int bestScore = int.MaxValue;
for (int i = 0; i < 9; i++)
{
if (board[i] != 'X' && board[i] != 'O')
{
board[i] = opponent;
int score = Mi