Files
CardGame/CardGame.Test.GamePlay2.WhenPlayerAWins/CardGame.Test.GamePlay2.WhenPlayerAWins.cpp
2024-06-27 00:45:18 +08:00

205 lines
4.4 KiB
C++
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#include <iostream>
using namespace std;
#include "SqList.h"
#include "SqQueue.h"
#include "SqStack.h"
#include "Functions.h"
// 发牌
void DealCards(int N, SqList<int>*& PA, SqList<int>*& PB, int times)
{
int* CardPile = new int[N]; // 发牌堆
srand((int)time(nullptr) + times); // 基于当前时间和游玩次数(对于测试代码,多次测试可能在同一秒完成)设置随机数种子
for (int i = 0; i < N; i++) CardPile[i] = 2; // 默认情况下每个面值有两张牌
for (int i = 0; i < N * 2; i++)
{
int j = 1, k = 1;
int num = rand() % N; // 获取一个 0~N-1 的随机数
while (true)
{
if (CardPile[num] != 0) // 如果该数对应面值的牌未发完
{
if (i % 2 == 0) // 发给PA
{
InsertElem_i(*PA, j++, num + 1);
CardPile[num]--;
}
else // 发给PB
{
InsertElem_i(*PB, k++, num + 1);
CardPile[num]--;
}
break;
}
else num = (num + 1) % N; // 若发完则检查下一位数字对应面值的牌
}
}
delete[] CardPile; // 释放发牌堆占用的内存
}
// 输出B的手牌
void DisplayPlayerBCards(int*& QB, int N)
{
for (int i = 0; i < N; i++)
for (int j = 0; j < QB[i]; j++)
cout << i + 1 << " ";
cout << endl;
}
bool IsPlayerAWin(int*& QB, int N)
{
for (int i = 0; i < N; i++)
if (QB[i] > 0) return false;
return true;
}
// 玩家B出牌
int PlayerBPlay(int*& QB, SqStack<int>& Desk, int N)
{
// 如果栈为空且B有两张相同面值的牌则出该面值的牌
if (StackEmpty(Desk))
for (int i = 1; i <= N; i++)
if (QB[i - 1] == 2)
return i;
// 如果栈非空,则从栈底遍历,找到第一张手牌中拥有的牌出之
for (int i = 0; i <= Desk.top; i++)
{
int card = Desk.base[i];
if (QB[card - 1] > 0)
return card;
}
// 如果以上情况都不满足,则随机出一张牌
int card;
do
card = rand() % N + 1;
while (QB[card - 1] == 0);
return card;
}
int GamePlay2(SqList<int>& PA, SqList<int>& PB, int N)
{
int winner = 0;
SqStack<int>* Desk = new SqStack<int>; // 牌桌上的牌
InitStack(*Desk, N * 2 + 1);
// 玩法2初始化
// 对于玩法2PA为先抓到的牌先出赢的牌加在牌尾PB为任意出牌
SqQueue<int>* QA = new SqQueue<int>;
InitQueue(*QA, N * 2 + 1);
// PB手牌存储方式下标为面值-1值为张数
int* QB = new int[N];
for (int i = 0; i < N; i++) QB[i] = 0;
// 将PA的牌放入QA
for (int i = 1; i <= N; i++)
{
int e = 0;
GetElem_i(PA, i, e);
EnQueue(*QA, e);
}
// 将PB的牌放入QB
for (int i = 1; i <= N; i++)
{
int e = 0;
GetElem_i(PB, i, e);
QB[e - 1]++;
}
// Step2 玩牌
int a = 0, b = 0, i = 0; // i的奇偶性决定出牌方
while (true)
{
int x = 0;
// 双方交替出牌
if (i++ % 2 == 0) {
DeQueue(*QA, a);
x = a;
}
else {
b = PlayerBPlay(QB, *Desk, N);
QB[b - 1]--;
x = b;
}
// 如果桌面上没有面值为X的牌则将牌放到牌桌上
if (FindElem(*Desk, x) == -1) Push(*Desk, x);
// 如果桌面上有面值为X的牌
else
{
int times = FindElem(*Desk, x);
if (IsPlayerA(i)) // 如果是A出的牌
{
// 将X放入牌尾
EnQueue(*QA, x);
// 将桌面上直到X的牌依次放入牌尾
for (int j = 0; j <= times; j++)
{
int e = 0;
Pop(*Desk, e);
EnQueue(*QA, e);
}
}
else // 如果是B出的牌
{
// 将X放入手牌
QB[x - 1]++;
// 将桌面上直到X的牌依次放入手牌
for (int j = 0; j <= times; j++)
{
int e = 0;
Pop(*Desk, e);
QB[e - 1]++;
}
}
}
// 判断是否有一方获胜
if (QueueEmpty(*QA))
{
winner = 2;
break;
}
else if (IsPlayerAWin(QB, N))
{
winner = 1;
break;
}
}
DestroyStack(*Desk);
DestroyQueue(*QA);
delete Desk;
delete QA;
delete[] QB;
return winner;
}
int main()
{
int counts;
cout << "Enter after how many times A win the program stops: ";
cin >> counts;
int i = 0;
int N = 9;
int flag = 0;
while (true)
{
i++;
SqList<int>* PA = new SqList<int>; // PA的手牌
InitList(*PA, N);
SqList<int>* PB = new SqList<int>; // PB的手牌
InitList(*PB, N);
DealCards(N, PA, PB, i);
int result = GamePlay2(*PA, *PB, N);
if (result == 1)
{
cout << "-----------------" << endl;
DispList(*PA);
DispList(*PB);
flag++;
}
DestroyList(*PA);
DestroyList(*PB);
delete PA;
delete PB;
if (flag == counts)
{
cout << "Totally run " << i << " times." << endl;
break;
}
}
}