DSS——项目课想的游戏

前排提示,C2已坠机,原因是怀疑我编辑的程序是用AI生成的唉唉。

//This blog allows use by GroupI Mathematical Ascension of the DIICSU, and is written by members of this group.If you wanna check my code, please download the code and locally run the following code which list all situations and store them in the output.txt.Thanks!

Check it!
 
/*
date: 2024-11-27 14:27:53
author : Tenryon

The main purpose of this procedure is to generate the number of games won and lost for all 
combinations of 10,000 random simulation scenarios, and thus to simulate the winning percentage of 
each scenario.
*/
#include <iostream>
#include <vector>
#include <algorithm>
#include <random>
#include <chrono>
#include <string>
#include <queue> 
#include <fstream>
using namespace std;

int N = 2;                                          // Number of players
bool fl[10] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};        // Mark for duplicate numbers
string deck;                                        // Table cards
int win1, win2, draw;
int mmm = 0;

// Enumerate all cases
vector<int> pre() {
    vector<int> numbers = {2, 3, 4, 5, 6, 7, 8, 9};
    vector<int> per;

    // Use next_permutation to generate all permutations
    do {
        int num = 0;
        for (int i = 0; i < 8; ++i) {
            num = num * 10 + numbers[i];
        }
        per.push_back(num);
    } while (next_permutation(numbers.begin(), numbers.end()));

    return per;
}
vector<int> A = pre();

// Build player structure
struct player {
    int score;
    vector<int> hand;

    // Manual operation function
    void opt(int i) {
        hand[7] = i % 10;
        hand[6] = i / 10 % 10;
        hand[5] = i / 100 % 10;
        hand[4] = i / 1000 % 10;
        hand[3] = i / 10000 % 10;
        hand[2] = i / 100000 % 10;
        hand[1] = i / 1000000 % 10;
        hand[0] = i / 10000000 % 10;
    }

    // Constructor
    player() {
        unsigned seed = chrono::system_clock::now().time_since_epoch().count() + rand();
        score = 0;
        for (int i = 2; i <= 9; i++) {
            hand.push_back(i);
        }
        shuffle(hand.begin(), hand.end(), default_random_engine(seed));
        
        /* Check randomness
        for (int j = 0; j < 8; j++) {
            cout << hand[j] << " ";
        }
        cout << endl;
        */
    }
};

void table(int turn, vector<player>& p) {

    /* Check cards
    for (int i = 0; i < N; i++) {
        cout << "player " << i + 1 << ": ";
        for (int j = 0; j < 8; j++) {
            cout << p[i].hand[j] << " ";
        }
        cout << endl;
    }
    */

    // Load table and same first step
    for (int i = 0; i < N; i++) {
        for (int j = turn * 2 - 2; j < turn * 2; j++) {
            if (j == turn * 2 - 2 && i == 0) {
                deck.push_back(p[i].hand[j] + '0');
                continue;
            }

            if (deck.find(p[i].hand[j] + '0') == string::npos) {
                deck.push_back(p[i].hand[j] + '0');
            } else {
                fl[p[i].hand[j]] = 1;
                deck.push_back('0');
            }
        }
    }

    /*
    for (int i = 0; i < deck.size(); i++) {
        cout << deck[i] << " ";
    }
    */
}

void thesame() {
    // Remove marked duplicate cards
    bool q = 0;
    for (int i = 2; i <= 8; i++) {
        while (fl[i] == 1 && deck.find(i + '0') != string::npos) {
            deck[deck.find(i + '0')] = '0';
        }
    }
}

void small() {
    // Small rule
    int op1 = 0;
    int s = 100;
    bool cnt = 0;
    for (int i = 0; i < deck.size(); i++) {
        if (deck[i] == '0') { continue; }
        s = min(s, deck[i] - '0');
    }
    if (s == 1 || s == 100) {
        return;
    }

    size_t op = deck.find(s + '0');
    if (op % 2 == 0) {
        op1 = 1;
    } else {
        op1 = -1;
    }

    for (int i = 0; i < deck.size(); i++) {
        if (deck[i] == '0') { continue; }
        if (i == op || i == op + op1) {
            continue;
        }
        if ((deck[i] - '0') % s == 0) {
            deck[i] = (deck[i] - '0') / s + '0';
            cnt = 1;
        }
    }
    if (cnt != 0) {
        deck[deck.find(s + '0')] = '1';
    }
}

// Clear the table
void clear() {
    for (; !deck.empty();) {
        deck.pop_back();
    }
}

// Calculate scores
void cscore(vector<player>& p) {
    for (int i = N - 1; i >= 0; i--) {
        p[i].score += (deck.back() - '0');
        deck.pop_back();
        p[i].score += (deck.back() - '0');
        deck.pop_back();
    }
}

// Output the winner
void win(vector<player>& p) {
    bool q = 0;
    int mm = p[0].score;
    queue<int> winer;
    winer.push(1);
    for (int i = 1; i < N; i++) {
        if (p[i].score > mm) {
            mm = p[i].score;
            for (; !winer.empty();) {
                winer.pop();
            }
            winer.push(i + 1);
        } else if (p[i].score == mm) {
            winer.push(i + 1);
        }
    }
    if (winer.size() == 1 && winer.front() == 1) {
        win1++;
    } else if (winer.size() == 1 && winer.front() == 2) {
        win2++;
    } else if (winer.size() == 2) draw++;

    while (!winer.empty()) {
        winer.pop();
    }
}

int main() {
    ofstream outFile("output.txt"); // Create an ofstream object and specify the file name
    if (!outFile.is_open()) {
        cerr << "Unable to open file for writing" << endl;
        return 1; // If the file cannot be opened, return an error code
    }

    int qqq = 0;

    for (int we = 0; we < A.size(); we++) {
        qqq = A[we];
        outFile << "Data " << A[we] << endl; // Redirect output to the file
        for (int tt = 0; tt < 10000; tt++) {
            for (int i = 0; i < 10; i++) {
                fl[i] = 0;
            }

            vector<player> p(N);
            p[0].opt(qqq);

            // Main program
            for (int i = 1; i <= 4; i++) {
                table(i, p);
                thesame();
                small();
                cscore(p);
                clear();
            }

            win(p);
        }
        outFile << endl;
        outFile << win1 << endl << win2 << endl << draw << endl; // Write results to the file
        outFile << endl;
        win1 = 0;
        win2 = 0;
        draw = 0;

    }
    outFile.close(); // Close the file
    return 0;
}

 

Rule(最终版)

1.玩家两到六人,年龄8岁以上
2.游戏开始时,每名玩家拥有2,3……9共八张牌以及两个0-9的骰子来记录累计得分。
3.每轮每人放置两张牌于桌面且背面朝上。当所有人出牌完毕后,再将所有牌翻转过来。
4.The Same:将全部出牌区中相同的牌放入弃牌区域。
5.The Smallest :现存桌面上小的那张牌为S牌,然后对桌面上除了S牌所出者出的另一张牌以外的所有牌进行判定。判定规则如下,如果能被S牌整除,则判定成功,将该牌的数值除以S牌的数值(用一个0-6的骰子放在上面,代表该牌现在的数值)。所有判定结束后,将S牌数值大小变为1,若没有一张判定成功,则S牌保留原本数值。
6.计分:每人将自己当前出牌区的牌的剩余数值求和,并加在累计得分上。
7.将桌面上所有牌移入弃牌区域,并进行下一轮。
8.四轮后游戏结束,累计得分最多者胜。有多人得分最多则均视为胜利者。

 

如果不是要写分析这个游戏估计会更有趣,原计划是1-10张牌,the smallest是将所有的牌除成相互不可约,能打多轮,最后冲线(100分),好玩多了水了个代码如下:

#include <iostream>
#include <vector>
#include <algorithm>
#include <random>
#include <chrono>
#include <string>
#include <queue>
using namespace std;

int N = 2;                                          //人数
bool fl[10]={0,0,0,0,0,0,0,0,0,0};                  //标记重复数字
string deck;                                        //桌面牌

//穷举所有情况
vector<int> pre(){
    vector<int> numbers = {2, 3, 4, 5, 6, 7, 8, 9};
    vector<int> per;

    // 使用next_permutation生成全排列
    do {
        int num = 0;
        for (int i = 0; i < 8; ++i) {
            num = num * 10 + numbers[i];
        }
        per.push_back(num);
    } while (next_permutation(numbers.begin(), numbers.end()));

    return per;
}
vector<int> A = pre();

// 构建player
struct player{
    int score;
    vector <int> hand;

    // 手操函数
    void opt(int i){
        hand[7]= i%10;
        hand[6]= i/10%10;
        hand[5]= i/100%10;
        hand[4]= i/1000%10;
        hand[3]= i/10000%10;
        hand[2]= i/100000%10;
        hand[1]= i/1000000%10;
        hand[0]= i/10000000%10;
    }
    
    //初始化
    player(){
        unsigned seed = chrono::system_clock::now().time_since_epoch().count()+rand();
        score = 0;
        for(int i = 2; i <= 9; i++){
            hand.push_back(i);
        }
        shuffle(hand.begin(), hand.end(), default_random_engine(seed));
        
        /*检查随机性
        for(int j = 0; j < 8; j++){
            cout<<hand[j]<<" ";
        }
        cout<<endl;
        */
    }
};



void table(int turn,vector <player> &p){

    
    /* 检查牌
    
    for (int i = 0; i < N; i++){
        cout<<"player "<<i+1<<": ";
        for(int j = 0; j < 8; j++){
            cout<<p[i].hand[j]<<" ";
        }
        cout<<endl;
    }
    */

    if(turn!= 1)cout<<endl;
    cout<<"turn: "<<turn<<endl;

    //加载桌面并same第一步
    for(int i = 0; i < N; i++){
        for (int j = turn*2-2; j < turn*2; j++){
            if(j == turn *2-2&&i == 0){
            deck.push_back(p[i].hand[j]+'0');
            continue;
            }

            if(deck.find(p[i].hand[j]+'0') == string::npos){
            deck.push_back(p[i].hand[j]+'0');
            }

            else{
                fl[p[i].hand[j]] = 1;
                deck.push_back('0');
            }
        }
    }

    /*
    for (int i = 0; i < deck.size(); i++){
        cout<<deck[i]<<" ";
    }
    */
}


void thesame(){
    //除去标记重复牌
    bool q = 0;
    for(int i = 2; i <= 8; i++){
        while(fl[i] == 1&&deck.find(i+'0') != string::npos){
            deck[deck.find(i+'0')]='0';
            if(q==0){q=1;cout<<"same "<<i;}
            else{cout<<" "<<i;}
        }
    }
    if(q)cout<<endl;
    cout<<"deck: "<<deck<<endl;
}


void small(){
    //small规则
    int op1 = 0;
    int s = 100;
    bool cnt = 0;
     for(int i = 0; i < deck.size(); i++){
        if(deck[i] == '0'){continue;}
        s = min(s, deck[i] - '0');
    }
    if (s == 1||s == 100){
        /*if(s==1)cout<<"small "<<'1'<<endl;
        else cout<<"deck null"<<endl;
        cout<<"deck: "<<deck<<endl;
        */
        return;
    }

    size_t op = deck.find(s+'0');
    if(op%2==0){
        op1 = 1;
    }
    else{
        op1 = -1;
    }
    
    for(int i = 0; i < deck.size(); i++){
        if(deck[i] == '0'){continue;}
        if(i==op||i==op+op1){
            continue;
        }
        if((deck[i]-'0')%s == 0){
            deck[i] = (deck[i]-'0')/s+'0';
            cnt =1;
        }
    }
    if(cnt!= 0){
        deck[deck.find(s+'0')] = '1';
    }
    cout<<"small "<<s<<endl;
    cout<<"deck: "<<deck<<endl;
}


//清理桌面
void clear(){
    for(;deck.empty() == false;){
            deck.pop_back();
    }
}

//计算分数
void cscore(vector<player> &p){
    for (int  i = N-1; i >= 0; i--)
    {
        p[i].score += (deck.back() - '0');
        deck.pop_back();
        p[i].score += (deck.back() - '0');
        deck.pop_back();
    }
    for(int i = 0; i < N; i++){
        cout<<"Player"<<" "<<1+i<<": "<<p[i].score<<endl;
    }
}

//输出赢家
void win(vector<player> &p){
    bool q = 0;
    int mm = p[0].score;
    queue<int> winer;
    winer.push(1);
    for (int  i =1; i < N; i++)
    {
        if(p[i].score > mm){
            mm = p[i].score;
            for(;!winer.empty();){
                winer.pop();
            }
            winer.push(i+1);
        }
        else if(p[i].score == mm){
            winer.push(i+1);
        }
    }
    while(!winer.empty()){
        if(!q){cout<<"winer: ";q=1;}
        cout << winer.front() << " ";
        winer.pop();
    }
}


int main(){
    vector <player> p(N);
    
    //自定义
    /*
    int qqq;
    cin>>qqq;
    p[0].opt(qqq);
    */

   //主程序
    for (int i = 1; i <= 4; i++)
    {
        table(i,p);
        thesame();
        small();
        cscore(p);
        clear();
    }

    
    win(p);

    
    
    return 0;
}
View Code

Conlusion:

1.刚开始jjt提出来雏形(初设1-10)时还挺有趣的,后面越想越恶心,有点无从下手
2.决策的收益情况过于模糊,人数一多计分复杂,被处理的牌也很多,也许干脆让有被整除牌的人不得分更方便,但这样又太简单了也许。
3. 2,3的进攻性,5,7的稳定得分,以及用2保护8,用3保护9的策略(后面发现29,38更优 )
4.如果是先到一百分的赛制,那决策也会更加有趣,洗牌更是给玩家清楚对方的操作习惯。没有双城之战我怎么活(┳Д┳)
posted @ 2024-11-25 15:44  Tenryon  阅读(80)  评论(0)    收藏  举报