diff --git a/CardGame/.idea/.idea.CardGame/.idea/.gitignore b/CardGame/.idea/.idea.CardGame/.idea/.gitignore
new file mode 100644
index 0000000..b856034
--- /dev/null
+++ b/CardGame/.idea/.idea.CardGame/.idea/.gitignore
@@ -0,0 +1,13 @@
+# 默认忽略的文件
+/shelf/
+/workspace.xml
+# Rider 忽略的文件
+/projectSettingsUpdater.xml
+/.idea.CardGame.iml
+/modules.xml
+/contentModel.xml
+# 基于编辑器的 HTTP 客户端请求
+/httpRequests/
+# Datasource local storage ignored files
+/dataSources/
+/dataSources.local.xml
diff --git a/CardGame/.idea/.idea.CardGame/.idea/encodings.xml b/CardGame/.idea/.idea.CardGame/.idea/encodings.xml
new file mode 100644
index 0000000..df87cf9
--- /dev/null
+++ b/CardGame/.idea/.idea.CardGame/.idea/encodings.xml
@@ -0,0 +1,4 @@
+
+
+
+
\ No newline at end of file
diff --git a/CardGame/.idea/.idea.CardGame/.idea/indexLayout.xml b/CardGame/.idea/.idea.CardGame/.idea/indexLayout.xml
new file mode 100644
index 0000000..7b08163
--- /dev/null
+++ b/CardGame/.idea/.idea.CardGame/.idea/indexLayout.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/CardGame/.idea/.idea.CardGame/.idea/vcs.xml b/CardGame/.idea/.idea.CardGame/.idea/vcs.xml
new file mode 100644
index 0000000..6c0b863
--- /dev/null
+++ b/CardGame/.idea/.idea.CardGame/.idea/vcs.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/CardGame/CardGame.cpp b/CardGame/CardGame.cpp
index 3f47372..f7dc53f 100644
--- a/CardGame/CardGame.cpp
+++ b/CardGame/CardGame.cpp
@@ -22,7 +22,14 @@ int main()
DealCards(N, PA, PB);
DispList(*PA);
DispList(*PB);
-
- GamePlay1(*PA,*PB,N);
- GamePlay2(*PA,*PB,N);
+
+ cout << "------------------------------" << endl;
+ cout << "Game Play 1" << endl;
+ GamePlay1(*PA, *PB, N);
+ cout << "------------------------------" << endl;
+ cout << "Game Play 2" << endl;
+ GamePlay2(*PA, *PB, N);
+
+ DestroyList(*PA);
+ DestroyList(*PB);
}
\ No newline at end of file
diff --git a/CardGame/CardGame.vcxproj b/CardGame/CardGame.vcxproj
index 7b34f64..5869263 100644
--- a/CardGame/CardGame.vcxproj
+++ b/CardGame/CardGame.vcxproj
@@ -133,7 +133,6 @@
-
diff --git a/CardGame/CardGame.vcxproj.filters b/CardGame/CardGame.vcxproj.filters
index 7ee0dd6..240ee54 100644
--- a/CardGame/CardGame.vcxproj.filters
+++ b/CardGame/CardGame.vcxproj.filters
@@ -38,9 +38,6 @@
头文件
-
- 头文件
-
头文件
diff --git a/CardGame/Functions.h b/CardGame/Functions.h
index 7ad582e..479c11c 100644
--- a/CardGame/Functions.h
+++ b/CardGame/Functions.h
@@ -20,12 +20,12 @@ inline void DealCards(int N, SqList*& PA, SqList*& PB)
{
if (i % 2 == 0) // 发给PA
{
- InsertElem_i(* PA, j++, num + 1);
+ InsertElem_i(*PA, j++, num + 1);
CardPile[num]--;
}
else // 发给PB
{
- InsertElem_i(* PB, k++, num + 1);
+ InsertElem_i(*PB, k++, num + 1);
CardPile[num]--;
}
break;
@@ -41,9 +41,7 @@ inline int FindElem(SqStack& S, int e)
{
int i = S.top; // 从栈顶开始查找
for (; i >= 0; i--)
- {
if (S.base[i] == e) return S.top - i; // 返回距离
- }
return -1;
}
@@ -51,4 +49,10 @@ inline int FindElem(SqStack& S, int e)
inline bool IsPlayerA(int i)
{
return i % 2 == 1;
+}
+
+// 返回栈元素数量
+inline int StackSize(SqStack& S)
+{
+ return S.top + 1;
}
\ No newline at end of file
diff --git a/CardGame/GamePlay1.cpp b/CardGame/GamePlay1.cpp
index 66e444b..6fea6eb 100644
--- a/CardGame/GamePlay1.cpp
+++ b/CardGame/GamePlay1.cpp
@@ -25,9 +25,9 @@ void GamePlay1(SqList PA, SqList PB, int N)
// 玩法1初始化
// 对于玩法1,双方均为先抓到的牌先出,赢的牌加在牌尾
SqQueue* QA = new SqQueue;
- InitQueue(*QA, 2 * N + 1);
+ InitQueue(*QA, N * 2 + 1);
SqQueue* QB = new SqQueue;
- InitQueue(*QB, 2 * N + 1);
+ InitQueue(*QB, N * 2 + 1);
// 将PA和PB的牌分别放入QA和QB
for (int i = 1; i <= N; i++)
{
@@ -95,7 +95,7 @@ void GamePlay1(SqList PA, SqList PB, int N)
break;
}
}
- delete Desk;
+ DestroyStack(*Desk);
DestroyQueue(*QA);
DestroyQueue(*QB);
}
\ No newline at end of file
diff --git a/CardGame/GamePlay2.cpp b/CardGame/GamePlay2.cpp
index 753eda4..d9d56ac 100644
--- a/CardGame/GamePlay2.cpp
+++ b/CardGame/GamePlay2.cpp
@@ -3,19 +3,70 @@ using namespace std;
#include "include/SqList.h"
#include "include/SqQueue.h"
#include "include/SqStack.h"
-#include "include/LinkList.h"
#include "FuncRef.h"
+#include "Functions.h"
+
+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;
+}
+
+void DisplayStatus(SqQueue& QA, int* QB, SqStack& Desk, int i, int N)
+{
+ cout << "------------------------------" << endl;
+ cout << "Round " << i << endl;
+ cout << "Player A: ";
+ DispQueue(QA);
+ cout << "Player B: ";
+ DisplayPlayerBCards(QB, N);
+ cout << "Desk: ";
+ DispStack(Desk);
+}
+
+bool IsPlayerBWin(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& 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;
+}
void GamePlay2(SqList PA, SqList PB, int N)
{
SqStack* Desk = new SqStack; // 牌桌上的牌
- InitStack(*Desk, N * 2);
+ InitStack(*Desk, N * 2 + 1);
// 玩法2初始化
// 对于玩法2,PA为先抓到的牌先出,赢的牌加在牌尾;PB为任意出牌
SqQueue* QA = new SqQueue;
- InitQueue(*QA, N + 1);
- LNode* QB;
- InitList(QB);
+ 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++)
{
@@ -28,8 +79,68 @@ void GamePlay2(SqList PA, SqList PB, int N)
{
int e = 0;
GetElem_i(PB, i, e);
- InsertElem_i(QB, i, e);
+ QB[e - 1]++;
}
- DispQueue(*QA);
- DispList(QB);
+ // 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]++;
+ }
+ }
+ }
+ DisplayStatus(*QA, QB, *Desk, i, N);
+ // 判断是否有一方获胜
+ if (QueueEmpty(*QA))
+ {
+ cout << "Player B wins!" << endl;
+ break;
+ }
+ else if (IsPlayerBWin(QB, N))
+ {
+ cout << "Player A wins!" << endl;
+ break;
+ }
+ }
+ DestroyStack(*Desk);
+ DestroyQueue(*QA);
+ delete[] QB;
}
\ No newline at end of file
diff --git a/CardGame/include/LinkList.h b/CardGame/include/LinkList.h
deleted file mode 100644
index a5833a6..0000000
--- a/CardGame/include/LinkList.h
+++ /dev/null
@@ -1,255 +0,0 @@
-#pragma once
-#include
-
-template
-struct LNode //链表结点
-{
- DT data; //数据域,存储数据元素值
- LNode* next; //指针域,指向下一个结点
-};
-
-//算法2.1
-template
-bool PriorElem_e(LNode* L, DT e, DT& pre_e) // 求值为e的元素前驱
-{
- int k;
- k = LocateElem_e(L, e); // 1.获取e的位序k
- if (k > 1) // 2.位序k大于1
- {
- GetElem_i(L, k - 1, pre_e); // 第k-1个元素为e的前驱
- return true;
- }
- else // 3.元素e无前驱
- return false; // 返回false
-}
-
-//【算法2.14】 创建空单链表
-template
-bool InitList(LNode*& L)
-{
- L = new LNode; // 1.创建头结点
- if (!L) exit(1); // 2.创建失败,退出
- L->next = NULL; // 3.创建成功
- return true; // 返回true
-}
-
-//【算法2.15】 尾插法创建n的元素
-template
-bool CreateList_1(LNode*& L, int n)
-{
- int i;
- LNode* p, * s;
- p = L; //1.工作指针初始化,指向尾结点
- cout << "依次输入" << n << "个数据元素:" << endl;
- for (i = 1; i <= n; i++) // 2.按元素位序正序创建各结点
- {
- s = new LNode; // 2.1 新建一个结点s
- if (!s) // 2.2 创建失败,返回false
- return false;
- cin >> s->data; // 2.3 输入结点值
- s->next = p->next; // 2.4 s 链在表尾
- p->next = s;
- p = s; // 2.5 工作指针指向 s
- }
- return true; // 3.创建成功,返回true
-}
-
-//【算法2.16】 头插法创建n个元素
-template
-bool CreateList_2(LNode* (&L), int n)
-{
- int i;
- LNode* s;
- cout << "逆序输入" << n << "个数据元素:" << endl;
- for (i = 1; i <= n; i++) // 1.按元素位序逆序创建各结点
- {
- s = new LNode; // 1.1 新建一个结点 s
- if (!s) // 1.2 创建失败,返回false
- return false;
- cin >> s->data; // 1.3 输入结点值
- s->next = L->next; // 1.4 s 在头结点后
- L->next = s;
- }
- return true; // 1.创建成功,返回true
-}
-
-//【算法2.17】
-template
-void DestroyList(LNode* (&L)) // 释放链表所占空间
-{
- LNode* p;
- while (L) // 1. 表非空,从头结点开始,依次释放结点
- {
- p = L; // 1.1 处理表头结点
- L = L->next; // 1.2 头指针后移
- delete p; // 1.3 释放表头结点所占内存
- }
- L = NULL; // 2.头指针指向空
-}
-
-//【算法2.18】 获取第i个元素
-template
-bool GetElem_i(LNode* L, int i, DT& e)
-{
- LNode* p; // 1.初始化
- p = L->next; // 1.1 设置工作指针,从首结点开始数结点
- int j = 1; // 1.2 计数器初始化
- while (p && j < i) // 2.定位到第i个元素结点
- {
- p = p->next; j++;
- }
- if (!p || j > i) // 3 未找到,返回false
- return false;
- else // 4. 找到
- {
- e = p->data; // 获取第i个元素值
- return true; // 返回true
- }
-}
-
-//【算法2.19】 查找值为e的元素位序
-template
-int LocateElem_e(LNode* L, DT e)
-{
-
- LNode* p; // 1.初始化从首元开始查找
- p = L->next; // 1.1从首元开始查找
- int j = 1; // 1.2 计数器初值
- while (p && p->data != e) // 2.顺序查找
- {
- p = p->next; // 2.1未找到指针后移
- j++; // 2.2 计数器增1
- }
- if (p == NULL) // 3. 判断是否找到
- return 0; // 3.1末找到,返回0
- else
- return j; // 3.2 找到,返回位序
-}
-
-//【算法2.20】 插入第i个元素
-template
-bool InsertElem_i(LNode*& L, int i, DT e)
-{
-
- int j = 0;
- LNode* p; // 1.初始化
- p = L; // 工作指针初始化
- while (p && j < i - 1) // 2. 定位到插入点前驱
- {
- p = p->next;
- j++;
- }
- if (!p || j > i - 1) // 3.判断定位是否成功:
- return false; // 3.1 定位失败,不能插入
- else // 3.2 定位成功
- {
- LNode* s;
- s = new LNode; // 3.2.1建立新结点
- s->data = e; // 3.2.2新结点赋值
- s->next = p->next; // 3.2.3结点S链接到p结点之后
- p->next = s;
- return true; // 3.2.4 插入成功,返回true
- }
-
-}
-
-//【算法2.21】 删除第i个元素
-template
-bool DeleElem_i(LNode* (&L), int i)
-{
-
- LNode* p, * q; //1.初始化:设置工作指针
- p = L; //查找从头结点开始
- int j = 0; //计数器初始化
- while (p->next && j < i - 1) //2.p定位到删除点的前驱
- {
- p = p->next;
- j++;
- }
- if (!p->next || j > i - 1) //3.删除位置不合理,不能删除
- return false; //返回false
- else //4.删除操作
- {
- q = p->next; //4.1暂存删除结点位置
- p->next = q->next; //4.2从链表中摘除删除结点
- delete q;
- return true; //4.3删除成功,返回true
- }
-}
-
-
-//【算法2.22】 修改第i个元素值
-template
-bool PutElem_i(LNode* (&L), int i, DT e)
-{
- LNode* p; // 1.初始化:设置工作指针
- p = L->next; // 从首结点开始,数结点
- int j = 1; // 计数器初始化
- while (p && j < i) // 2.查找第i个元素结点
- {
- p = p->next; j++;
- }
- if (!p || j > i) // 3.元素不存在,返回false
- return false;
- else // 4.定位成功
- {
- p->data = e; // 修改元素值
- return true; // 返回true
- }
-}
-
-// 释放链表所占空间
-template
-void ClearList(LNode* (&L))
-{
-
- LNode* p;
- while (L->next) // 从首元结点开始,依次释放结点
- {
- p = L->next;
- L->next = p->next;
- delete p;
- }
- cout << endl << "表已清空!" << endl;
-}
-
-
-//【算法2.23】 测表长
-template
-int ListLength(LNode* L)
-{ // 1.初始化
- int len = 0; // 1.1 结点计数器赋初值0
- LNode* p; // 1.2设置工作指针
- p = L; // 指向头结点
- while (p->next) // 2.数结点个数。有后继结点,
- {
- len++; p = p->next; // 结点数增1,指针后移
- }
- return len; // 3.返回表长
-}
-
-//
-template
-bool ListEmpty(LNode* L) //测表空
-{
- if (L->next == NULL)
- return true; //空表,返回1
- else
- return false; //不空,返回0
-}
-
-
-//【算法2.24】 遍历表
-template
-void DispList(LNode* L) // 显示表内容
-{
- LNode* p; // 1. 设置工作指针
- p = L; // 从首元结点开始遍历
- while (p->next) // 2.依次输出各结点值
- {
- p = p->next; cout << p->data << " ";
-
-
- }
- cout << endl;
-}
diff --git a/ExpReportTemplate.dotx b/ExpReportTemplate.dotx
new file mode 100644
index 0000000..d92ed53
Binary files /dev/null and b/ExpReportTemplate.dotx differ