You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C#实现Mastermind游戏:玩家与电脑代码比对逻辑异常问题

Fixing the Pin Counting Bug in Your C# Mastermind Game

Hey there! Let's tackle that annoying overcounting issue with your Mastermind pin markers. The core problem with your current code is that the alreadyOcurredNumber boolean is too simplistic—it only tracks a single flag per outer loop iteration, which can't properly handle duplicate numbers or prevent reusing the same position in either the player's or opponent's code for multiple matches.

Why Your Current Approach Fails

For example, if the opponent's code is [1,1,2,3] and the player guesses [1,1,1,4], your code would incorrectly count more "right number wrong position" pins than it should. This happens because you're not tracking which specific positions in either array have already been matched, so the same opponent's 1 might get counted multiple times against different player 1s.

The Correct Approach to Count Pins

Mastermind's pin counting needs two distinct steps to avoid overcounting:

  1. First count exact matches (same number, same position). Mark these positions as used so they aren't reused in the next step.
  2. Then count partial matches (same number, different position) using only the unused positions from both arrays.

Modified Code for Pin Counting

Replace your existing pin-counting loop with this updated logic:

int rightGuessRightIndex = 0;
int rightGuessWrongIndex = 0;

// Create boolean arrays to track which positions have been matched
bool[] usedOpponent = new bool[codeOfOpponent.Length];
bool[] usedPlayer = new bool[codeOfPlayer.Length];

// Step 1: Count exact matches (right number, right position)
for (int i = 0; i < codeOfOpponent.Length; i++)
{
    if (codeOfOpponent[i] == codeOfPlayer[i])
    {
        rightGuessRightIndex++;
        usedOpponent[i] = true;
        usedPlayer[i] = true;
    }
}

// Step 2: Count partial matches (right number, wrong position)
for (int i = 0; i < codeOfPlayer.Length; i++)
{
    if (!usedPlayer[i]) // Only check unused player positions
    {
        for (int j = 0; j < codeOfOpponent.Length; j++)
        {
            if (!usedOpponent[j] && codeOfOpponent[j] == codeOfPlayer[i])
            {
                rightGuessWrongIndex++;
                usedOpponent[j] = true; // Mark this opponent position as used to avoid re-counting
                break; // Move to next player number once we find a match
            }
        }
    }
}

How This Works

  • The usedOpponent and usedPlayer arrays keep track of which positions in each code have already been accounted for (either as exact matches or partial matches).
  • We first handle exact matches to ensure those positions aren't considered again for partial matches.
  • For partial matches, we only look at unused positions in both arrays, and once we find a match, we mark the opponent's position as used so it can't be matched again to another player number.

Bonus: Fixing the Turn Loop

You might also notice your current code only lets the player guess once. To add proper turn handling, wrap the guess and pin-counting logic in a while loop, like this:

int amountOfTurns = 0;
const int maxTurns = 20;
bool[] usedOpponent = new bool[codeOfOpponent.Length];
bool[] usedPlayer = new bool[codeOfPlayer.Length];

while (amountOfTurns < maxTurns)
{
    // Get player's guess
    codeOfPlayer = mastermind.createCodeOfPlayer(codeOfPlayer);
    
    // Reset pin counts and used flags for each turn
    rightGuessRightIndex = 0;
    rightGuessWrongIndex = 0;
    Array.Clear(usedOpponent, 0, usedOpponent.Length);
    Array.Clear(usedPlayer, 0, usedPlayer.Length);
    
    // Run exact match counting
    for (int i = 0; i < codeOfOpponent.Length; i++)
    {
        if (codeOfOpponent[i] == codeOfPlayer[i])
        {
            rightGuessRightIndex++;
            usedOpponent[i] = true;
            usedPlayer[i] = true;
        }
    }
    
    // Run partial match counting
    for (int i = 0; i < codeOfPlayer.Length; i++)
    {
        if (!usedPlayer[i])
        {
            for (int j = 0; j < codeOfOpponent.Length; j++)
            {
                if (!usedOpponent[j] && codeOfOpponent[j] == codeOfPlayer[i])
                {
                    rightGuessWrongIndex++;
                    usedOpponent[j] = true;
                    break;
                }
            }
        }
    }
    
    // Display results
    Console.WriteLine("\nRight number and right place: {0}", rightGuessRightIndex);
    Console.WriteLine("Right number and wrong place: {0}", rightGuessWrongIndex);
    
    // Check for win condition
    if (codeOfPlayer.SequenceEqual(codeOfOpponent))
    {
        Console.WriteLine($"You won in {amountOfTurns + 1} turns!");
        break;
    }
    
    amountOfTurns++;
    Console.WriteLine($"\nTry again! You have {maxTurns - amountOfTurns} turns left.");
}

if (amountOfTurns == maxTurns)
{
    Console.WriteLine("\nGame over! The opponent's code was:");
    foreach (int num in codeOfOpponent)
    {
        Console.Write(num);
    }
}

This will let the player keep guessing until they win or run out of turns.

内容的提问来源于stack exchange,提问作者Elipse

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.12 04:15:23