簡體   English   中英

Java中的匹配紙牌游戲

[英]Matching Card Game in Java

你好,

我正在制作一個匹配的紙牌游戲,但我不知道該怎么做。 我希望有人可以幫助解釋我能做些什么來解決這個問題。

以下是規格:

在 Pairs 紙牌游戲中,目標是翻轉配對的卡片。

https://en.wikipedia.org/wiki/Concentration_(game)以下是我們考慮的對的變化規則。

游戲開始時有n張面朝下的牌,其中n是4的倍數。每種牌有4張,牌上標有字母a、b、...。 . . . 例如,如果 n==24,則卡片有 6 種類型:a、b、c、d、e 和 f。 說 1*4<=n 和 n<=4*26。

在每一輪,玩家翻轉 2 張牌,一次一張,面朝下。 如果兩次翻轉的類型相同,則匹配的牌面朝上。 如果 2 次翻轉不匹配,則將不匹配的卡返回到面朝下的 position。 當所有牌都匹配時,游戲結束,得分是翻轉的總數。 (翻轉一對牌算作 2 次翻轉,因此最好的分數是 n 次翻轉。)

編寫一個名為 MatchCardGame 的公共 class,其中包含實現此對子游戲的以下成員。 PlayCard.java 中的起始代碼應該讓您了解如何使用 MatchCardGame。

除了指定的之外,MatchCardGame 應該沒有其他公共字段、方法和構造函數。 但是,它可能也應該有額外的私有字段、方法或構造函數。

公共最終詮釋 n;

是構造函數設置的游戲大小。

構造函數

公共 MatchCardGame(int n);

初始化一個總共有 n 張牌的紙牌游戲。 假設 n 是 4 的倍數,並且 4<=n && n<=4*26。 沒有洗牌(在問題 2 中解釋)牌 0、1、2 和 3 應該是 a,牌 4、5、6 和 7 應該是 b,依此類推。

方法

公共字符串 boardToString();

將電路板的 state 轉換為適當的字符串表示形式。 您可以自由選擇自己的表示,但它必須合理地代表游戲的 state。

方法

公共 boolean 翻轉(int i);

打卡號 i。 如果卡 i 因為正面朝上而無法打出,或者如果 i 是無效卡號,則返回 false。 如果 i 是可以打的牌號,打出牌 i 並返回 true。

方法

公共 boolean wasMatch();

如果前一對是匹配的,則返回 true,否則返回 false。 只有在成功調用了偶數次之后,並且在調用 FlipMismatch 之前,才應調用此方法。 (成功調用翻轉是導致翻轉並返回 true 的調用。)

方法

public char previousFlipIdentity();

將先前翻轉的卡片的面作為字符返回。 此方法僅應在翻牌后調用。

方法

公共無效翻轉不匹配();

將不匹配的對恢復為面朝下的 position。 只有在兩次調用翻轉導致不匹配后才應調用此方法。

方法

公共 boolean gameOver();

如果所有卡都匹配並且游戲結束,則返回 true,否則返回 false。 方法 public int getFlips();

返回到目前為止已執行的卡片翻轉總數。

評論。 MatchCardGame 代表游戲的物理 state,而不是玩家。 MatchCardGame 與人類或 AI 玩家可能采用的游戲策略無關。

評論。 問題指定了如何使用這些方法。 例如,MatchCardGame 的構造函數的輸入 n 需要是 4 的倍數。當違反這些要求時,您不必進行任何類型的錯誤處理,盡管使用斷言將有助於調試。

到目前為止,我有以下內容:

public class MatchCardGame {
//Private classes
private boolean facingup;
private char[] board;
private int flips = 0;
private int matches = 0;
private int currentflip;

//Public classes
public final int n;

public MatchCardGame(int n) {
    for (int i = 0; i < n; i++) {
        if (i % 4 == 0) {
            this.board[i] = 'a';
        }
        else if (i % 4 == 1) {
            this.board[i] = 'b';
        }
        else if (i % 4 == 2) {
            this.board[i] = 'c';
        }
        else {
            this.board[i] = 'd';
        }
    }
}

public String boardToString() {
    String stringboard = "";
    for (int i; i < n; i++) {
        if (facingup){
            stringboard += stringboard + "[" + this.board[i] + "] ";
        }
        else {
            stringboard += "[-] ";
        }
    }
    return stringboard;
}

public boolean flip(int i) {
    flips++;
    if (i < 0 || i >= n || currentflip == ((int) this.board[i]) % 32) {
        return false;
    }
    else {
        if (flips % 2 != 0) {
            currentflip = ((int) board[i]) % 32;
            facingup = true;
            return true;
        }
        else if (board[i] == this.board[i]) {
            currentflip = -1;
            this.facingup = true;
            board [i] = '0';
            this.board[i] = '0';
            matches += 2;
            return true;
        }
    }
}

public boolean wasMatch() {
    if (currentflip == -1) {
        return true;
    }
    else {
        return false;
    }
}

public char previousFlipIdentity() {
    return board [i];
}

public void flipMismatch() {
    facingup = false;
    this.facingup = false;

}

public boolean gameOver() {
    if (matches == n) {
        return true;
    }
    else {
        return false;
    }
}

public int getFlips() {
    return flips;
}}

任何援助將不勝感激。

試着在你的腦海中走過它。

  • 您已獲得一組卡片
  • 一張牌, x被翻轉
  • 接下來翻另一張牌; 如果它與之前的x相同,則刪除兩張卡
  • 如果與前一個不同,則忽略兩次翻轉。
  • 繼續這些步驟,直到所有卡片都匹配並且沒有剩余卡片

那么要將其轉換為代碼,您需要跟蹤哪些內容?

  • 所有卡片及其類型( ab等)
  • State卡:翻轉或不翻轉
  • 所有卡的通用 state:匹配或仍然存在(請記住,如果匹配,我們將其刪除)
  • 翻轉次數

我們如何跟蹤這一點?

  • 我們可以在數組char[] board中跟蹤卡片的類型
  • 維護private int flips以跟蹤翻轉次數,並維護private int matches以跟蹤匹配,最初0
  • 維護一個private int currentlyFlippedCard來存儲第一張翻轉卡片的索引。
  • 如果是第一次翻轉,則將其存儲在currentlyFlippedCard中。
  • 每次翻轉卡片時遞增int flipsflips++ )。
  • 如果是第二次翻轉,請檢查卡片類型是否與currentlyFlippedCard中的卡片類型匹配。
    • 你怎么知道翻轉是第一次還是第二次? 因為我們每次都增加flips
    • 對於第一次翻轉, flip == 1 第二, flip == 2 如果它再次翻轉,它將變為flip == 3 ,我們應該將其作為第一次翻轉。
    • 由此,我們可以說當flip為奇數時為第一次翻轉,當flip為偶數時為第二次。
  • 如果兩次翻轉都不匹配:不要進行任何更改。
  • 如果兩個翻轉匹配:在char[] board中將兩個翻轉的兩個索引都更改為'0'以將其標記為非活動; int matches增加2
  • 所以下次調用 flip( i ) 時,檢查board[i] != '0'是否,這將確保它在游戲中仍然處於活動狀態
  • 你怎么知道比賽是否結束? 如果所有卡都匹配,則游戲結束。 因此,如果matches == n ,則所有卡都匹配。
  • 您需要知道上一次翻轉是否匹配(對於wasMatch() )。 為此,您可以維護一個boolean來跟蹤它; 或者另一種方式是,您可以使用變量currentlyFlippedCard本身。
    對於第二種方式:
    • 當第二次翻轉不匹配時,什么都不做( currentlyFlippedCard將具有前一次翻轉的索引,這意味着currentlyFlippedCard >= 0
    • 當第二次翻轉是匹配時,隨着matches的增加,設置currentlyFlippedCard = -1
    • 當您需要調用wasMatch()時,如果flips是偶數並且 currentFlippedCard currentlyFlippedCard == -1則返回true
  • 對於boardToString() ,只需使用循環將board[]中的所有字符一個一個地放入一個String中。
    • 這里, 0表示匹配; 您可以添加一個if檢查以查看它是否為 == 0並在插入String時將其更改為另一個字符。
    • 當前翻轉的卡片也是如此; 您可以檢查該索引何時出現,並添加*或其他內容以指示它已翻轉。

這是一個簡短的概述,您只需將其轉換為代碼即可。 到目前為止,我沒有添加實際代碼,因為如果您自己嘗試一下,它會對您有所幫助。
一切順利,繼續學習::)

編輯1(評論后):
我猜是在每第二次翻轉后調用wasMatch()嗎? 我認為它不會,並且不小心將遞增索引放入了flip()
因此,由於wasMatch()是一個單獨的方法,您可以為翻轉的卡片維護 2 個變量(比如 currentFlippedCard1 和currentlyFlippedCard2 ),並在currentlyFlippedCard1 wasMatch()期間遞增。
至於flipMismatch() :規范說它應該“將其恢復為面朝下位置”。 您可以不進行任何更改,也可以將currentlyFlippedCard1currentlyFlippedCard2更改為一些默認值,例如-2

編輯2(評論后):
對於previousFlipIdentity()

  • 檢查int flips以查看前一個翻轉是第一次還是第二次翻轉(通過檢查int flips是奇數還是偶數)
  • 如果第一次翻轉,返回board[currentlyFlippedCard1]
  • 如果第二次翻轉,返回board[currentlyFlippedCard2]

我的建議是:先實現你知道的核心方法。 一旦你運行了一些方法,你就會有一個更好的想法,你可以添加更多的功能。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM