根據指定規則生成遊戲選項編碼實戰

入遇到這樣的需求ios

「有不定數量的遊戲選項和不定的遊戲人數選項給用戶選擇,咱們按照  遊戲人數<<24 | 遊戲規則A<<16 | 遊戲規則B<<8 | 遊戲規則C      遊戲規則D<<24 | 遊戲規則E<<16 | 遊戲規則F<<8 | 遊戲規則G ........  來生成全部規則可能選中和未選中的遊戲碼」c++

該需求中,不定數量的遊戲選項和遊戲人數須要動態輸入  咱們須要使用讀取配置文件來獲取多少遊戲人數和遊戲規則 這是待實現的功能1程序員

根據獲取數量的遊戲選項 咱們要生成全部可能的選中和未選中的排列組合  這是待實現的功能2windows

根據生成排列組合按照規則生成遊戲碼 還要說明遊戲碼中那些遊戲選項被選中,也意味着須要進行排列組合和遊戲規則的映射 這是待實現的功能3數組

 

讀取配置文件來獲取多少遊戲人數和遊戲規則 能夠使用狀態機分析配置文件 這以前已經有文章進行了介紹服務器

地址 ide

 

 

據獲取數量的遊戲選項 咱們要生成全部可能的選中和未選中的排列組合 能夠使用遞歸回溯來進行計算函數

整個流程以下編碼

假設遊戲規則有三個  遊戲規則 A B C lua

步驟1 假設遊戲規則A 被選中  生成編碼1 

步驟2 假設遊戲規則B 被選中 生成編碼11

步驟3 假設遊戲規則C 被選中 生成第一個完整編碼111 

咱們回退到步驟2 假設遊戲規則B 被選中後  步驟3 假設遊戲規則C未被選中 生成第二個完整編碼 110  以此類推 。。。。。。

流程示意圖

整個過程描述比較繁瑣 可是對於使用遞歸回溯的函數 則十分簡潔

 

void fillVecInner(int fillPos, map<int, string>& methodNumName) {
    if (fillPos == method_count) {    //排列組合的位數與遊戲選項的數目相同 說明生成了一個完整的排列組合 須要記錄或者顯示

        for (int i = 0; i < vec.size(); i++) {
            if (1 == vec[i]) {
                std::cout << methodNumName[i] << " ";
            }
        }
        std::cout << std::endl;
        std::cout << std::endl;
        return;
    }

    for (int i = 0; i < 2; i++) {
        vec.push_back(i);    //插入0 或者 1 
        fillVecInner(fillPos + 1, methodNumName);
        vec.pop_back();        //復原 進行下一次的插入
    }
}
View Code

 

 

遊戲規則名稱和生成排列組合的映射就比較簡單了  在Cpp裏就是一個map容器搞定

void GenmethodCode() {
        int iarr[3] = { 0 };
        for (int i = 0; i < sizeof(iarr) / sizeof(iarr[0]); i++) {
            if (i < vec.size()) {
                iarr[i] = vec[i];
            }
        }
        //打印根據遊戲選項生成的遊戲碼
        Caluateone(player_count, iarr[0], iarr[1], iarr[2]);

        if (vec.size() > 3) {

            int iarr[4] = { 0 };
            for (int i = 0; i < sizeof(iarr) / sizeof(iarr[0]); i++) {
                if (i+3 < vec.size()) {
                    iarr[i] = vec[i+3];
                }
            }
            //打印根據遊戲選項生成的遊戲碼
            Caluatetwo( iarr[0], iarr[1], iarr[2], iarr[3]);
        }
    }
    
View Code
void GenmethodCode() {
        int iarr[3] = { 0 };
        for (int i = 0; i < sizeof(iarr) / sizeof(iarr[0]); i++) {
            if (i < vec.size()) {
                iarr[i] = vec[i];
            }
        }
        //打印根據遊戲選項生成的遊戲碼
        Caluateone(player_count, iarr[0], iarr[1], iarr[2]);

        if (vec.size() > 3) {

            int iarr[4] = { 0 };
            for (int i = 0; i < sizeof(iarr) / sizeof(iarr[0]); i++) {
                if (i+3 < vec.size()) {
                    iarr[i] = vec[i+3];
                }
            }
            //打印根據遊戲選項生成的遊戲碼
            Caluatetwo( iarr[0], iarr[1], iarr[2], iarr[3]);
        }
    }
View Code

 

 

所有代碼以下

  1 #pragma once
  2 
  3 #include <vector>
  4 #include <iostream>
  5 
  6 using namespace std;
  7 
  8 /*
  9 *做 者: itdef
 10 *歡迎轉帖 請保持文本完整並註明出處
 11 *技術博客 http://www.cnblogs.com/itdef/
 12 *技術交流羣 羣號碼:432336863
 13 *歡迎c c++ windows驅動愛好者 服務器程序員溝通交流
 14 *部分老代碼存放地點
 15 *http://www.oschina.net/code/list_by_user?id=614253
 16 */
 17 
 18 class GenMethodArray {
 19 public:
 20     GenMethodArray(int MethodCount ,int playerCount):method_count(MethodCount), player_count(playerCount){}
 21     ~GenMethodArray() {}
 22 
 23     void fillVec(int fillPos,  map<int, string>& methodNumName) {
 24         fillVecInner(0, methodNumName);
 25     }
 26     void Caluateone(int playerNum, int j1, int j2, int j3) {
 27         long i1 = 0;
 28 
 29         i1 |= (playerNum << 24);
 30 
 31         i1 |= (j1 << 16);
 32 
 33         i1 |= (j2 << 8);
 34 
 35         i1 |= j3;
 36 
 37         std::cout << std::hex << "first = 0x" << i1 << std::endl;
 38         //std::cout << "first = " << i1 << std::endl;
 39     }
 40 
 41     void Caluatetwo(int j4, int j5, int j6, int j7) {
 42         long i1 = 0;
 43 
 44         i1 |= (j4 << 24);
 45 
 46         i1 |= (j5 << 16);
 47 
 48         i1 |= (j6 << 8);
 49 
 50         i1 |= j7;
 51 
 52         std::cout << std::hex << "tow = \t0x" << i1 << std::endl;
 53         //std::cout << "tow = \t" << i1 << std::endl;
 54     }
 55 
 56     void GenmethodCode() {
 57         int iarr[3] = { 0 };
 58         for (int i = 0; i < sizeof(iarr) / sizeof(iarr[0]); i++) {
 59             if (i < vec.size()) {
 60                 iarr[i] = vec[i];
 61             }
 62         }
 63         //打印根據遊戲選項生成的遊戲碼
 64         Caluateone(player_count, iarr[0], iarr[1], iarr[2]);
 65 
 66         if (vec.size() > 3) {
 67 
 68             int iarr[4] = { 0 };
 69             for (int i = 0; i < sizeof(iarr) / sizeof(iarr[0]); i++) {
 70                 if (i+3 < vec.size()) {
 71                     iarr[i] = vec[i+3];
 72                 }
 73             }
 74             //打印根據遊戲選項生成的遊戲碼
 75             Caluatetwo( iarr[0], iarr[1], iarr[2], iarr[3]);
 76         }
 77     }
 78     
 79 
 80 private:
 81     void fillVecInner(int fillPos, map<int, string>& methodNumName) {
 82         if (fillPos == method_count) {
 83             //打印遊戲選項名稱 若被選中
 84             for (int i = 0; i < vec.size(); i++) {
 85                 if (1 == vec[i]) {
 86                     std::cout << methodNumName[i] << " ";
 87                 }
 88             }
 89             std::cout << std::endl;
 90 
 91             /*for (int i = 0; i < vec.size(); i++) {
 92                 std::cout << vec[i];
 93             }*/
 94             //此函數中  打印根據遊戲選項生成的遊戲碼
 95             GenmethodCode();
 96             std::cout << std::endl;
 97             std::cout << std::endl;
 98             return;
 99         }
100 
101         for (int i = 0; i < 2; i++) {
102             vec.push_back(i);
103             fillVecInner(fillPos + 1, methodNumName);
104             vec.pop_back();
105         }
106     }
107 
108     int player_count;
109     int method_count;
110     vector<int> vec;
111 };
GenMethodArray.h
 1 #pragma once
 2 #include <iostream>
 3 #include <fstream>
 4 #include <cassert>
 5 #include <string>
 6 #include <iostream>
 7 #include <vector>
 8 #include <map>
 9 
10 using namespace std;
11 
12 /*
13 *做 者: itdef
14 *歡迎轉帖 請保持文本完整並註明出處
15 *技術博客 http://www.cnblogs.com/itdef/
16 *技術交流羣 羣號碼:432336863
17 *歡迎c c++ windows驅動愛好者 服務器程序員溝通交流
18 *部分老代碼存放地點
19 *http://www.oschina.net/code/list_by_user?id=614253
20 */
21 
22 const string FILE_NAME = "config.txt";
23 
24 class ReadConfig {
25 public:
26     ReadConfig(string filename="") {
27         if (filename.empty()) {
28             file_name = FILE_NAME;
29         }
30         else {
31             file_name = filename;
32         }
33     }
34     ~ReadConfig(){}
35 
36     map<string, string> Do() {
37         tar_path.clear();
38         ifstream fin;
39         fin.open(file_name);
40         if (false == fin.is_open()) {
41             std::cerr << "open file failed!!" << std::endl;
42             return tar_path;
43         }
44         string s;
45 
46         while (getline(fin, s))
47         {
48             if ( '#' == s[0] || ( '/' == s[0]  && '/' == s[1]))
49                 continue;
50             size_t pos = s.find_first_of("=");
51             if (pos == std::string::npos || pos + 1 >= s.size())
52                 continue;
53             string targetName = s.substr(0, pos);
54             string path = s.substr(pos + 1);
55             std::cout << targetName << " = " << path << std::endl;
56             if(path[0] != ' ')
57                 tar_path[targetName] = path;
58         }
59         fin.close();
60 
61         return tar_path;
62     }
63 
64 private:
65     map<string, string> tar_path;
66     string file_name;
67 
68 };
ReadConfig.h
 1 // CalculatePlayMethod.cpp: 定義控制檯應用程序的入口點。
 2 //
 3 
 4 #include "stdafx.h"
 5 #include "ReadConfig.h"
 6 #include "GenMethodArray.h"
 7 
 8 /*
 9 *做 者: itdef
10 *歡迎轉帖 請保持文本完整並註明出處
11 *技術博客 http://www.cnblogs.com/itdef/
12 *技術交流羣 羣號碼:432336863
13 *歡迎c c++ windows驅動愛好者 服務器程序員溝通交流
14 *部分老代碼存放地點
15 *http://www.oschina.net/code/list_by_user?id=614253
16 */
17 
18 
19 int main()
20 {
21     //獲取配置
22     ReadConfig readcf;
23     map<string, string> targetMethod = readcf.Do();
24     if (targetMethod.size() == 0) {
25         std::cerr << "get config error! exit!!" << std::endl;
26         return -1;
27     }
28     
29     //獲取玩家人數
30     int playerCount = atoi( targetMethod["playerNum"].c_str());
31     if (0 == playerCount) {
32         playerCount = 4;
33     }
34 
35     //獲取玩法編號和玩法名稱
36     map<int, string> methodNumName;
37     for (const auto& e : targetMethod) {
38         if (e.first != "playerNum" && e.second != "") {
39             //根據玩法標識最後一位的字符 與 ‘0’ 字符的差值 就是該字符表示的數值
40             //考慮到 數組與實際位值可能差1  因此是- ‘1’ 而不是 - ‘0’
41             int i = (e.first)[e.first.size() - 1] - '1';
42             methodNumName[i] = e.second;
43         }
44     }
45 
46     //生成玩法的排列組合
47     GenMethodArray genMeArr(methodNumName.size(), playerCount);
48     genMeArr.fillVec(0, methodNumName);
49 
50     system("pause");
51     return 0;
52 }
CalculatePlayMethod.cpp

配置文件內容

#註釋能夠使用 // 或者 #

playerNum=3
playMethod1=遊戲模式A
playMethod2=遊戲模式B
playMethod3=遊戲模式C
playMethod4=遊戲模式D
playMethod5=遊戲模式E
playMethod6=
playMethod7=
playMethod8=
playMethod9=
//目前僅支持 7種玩法之內配置

運行效果如圖

 

 1 // 1111.cpp : 此文件包含 "main" 函數。程序執行將在此處開始並結束。
 2 //
 3 
 4 #include "pch.h"
 5 #include <iostream>
 6 #include <vector>
 7 #include <string>
 8 
 9 
10 using namespace std;
11 
12 vector<vector<int>> init = {
13     {4},{0,1,2},{0,1},{0,1}
14 };
15 vector<string> gv;
16 void findCombination (int index, const string& s) {
17     if (index == 4) {
18         gv.push_back(s);
19         return;
20     }
21     vector<int> v = init[index];
22     for (int i = 0; i < v.size(); i++) {
23         findCombination(index + 1, s + to_string(v[i]));
24     }
25 
26 }
27 int main()
28 {
29     std::cout << "Hello World!\n"; 
30     findCombination(0,"");
31     for (int i = 0; i < gv.size(); i++) {
32         std::cout << gv[i] << std::endl;
33     }
34 }
35 
36 // 運行程序: Ctrl + F5 或調試 >「開始執行(不調試)」菜單
37 // 調試程序: F5 或調試 >「開始調試」菜單
38 
39 // 入門提示: 
40 //   1. 使用解決方案資源管理器窗口添加/管理文件
41 //   2. 使用團隊資源管理器窗口鏈接到源代碼管理
42 //   3. 使用輸出窗口查看生成輸出和其餘消息
43 //   4. 使用錯誤列表窗口查看錯誤
44 //   5. 轉到「項目」>「添加新項」以建立新的代碼文件,或轉到「項目」>「添加現有項」以將現有代碼文件添加到項目
45 //   6. 未來,若要再次打開此項目,請轉到「文件」>「打開」>「項目」並選擇 .sln 文件
View Code
相關文章
相關標籤/搜索