2 Star 2 Fork 0

Woding/诺曼底登陆战棋

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
克隆/下载
main.cpp 20.17 KB
一键复制 编辑 原始数据 按行查看 历史
Woding 提交于 2024-05-12 20:58 . 删了两段注释
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627
#include<iomanip>
#include<windows.h>
#include<fstream>
#include<cmath>
#include"main.h"
//TODO:变量名称规范化
using namespace std;
int dice(int n){
return rand()%n+1;
}
State::State(int x,int y){
this->x=x;
this->y=y;
this->score=scores[x][y];
this->name=names[x][y];
this->city=cities[x][y];
this->supplypoint=supplypoints[x][y];
if(this->city>0) this->controller=1;
if(x==2&&y==2) this->have_fortress=1;
}
void State::setTroop(Troops troop){
this->troop=&troop;
}
void State::clearTroop(){
this->troop=NULL;
}
Troops* State::getTroop(){
return this->troop;
}
void State::setCtrl(int n){
this->controller=n;
}
int State::getCtrl(){
return this->controller;
}
int State::getScore(){
return this->score;
}
void State::setRoad(pair<int,int> dest){
this->roadto.push_back(dest);
}
void State::setFort(bool value){
this->have_fortress=value;
}
bool State::getFort(){
return this->have_fortress;
}
int State::getCity(){
return this->city;
}
Troops::Troops(int atk,int def,int mov,int turn,string name,int pl){
this->atk=atk;
this->def=def;
this->mov=mov;
this->turn=turn;
this->name=name;
this->pl=pl;
}
void Troops::setPos(int nx,int ny){
states[{x,y}].clearTroop();
this->x=nx;
this->y=ny;
states[{nx,ny}].setTroop(*this);
}
pair<int,int> Troops::getPos(){
return {this->x,this->y};
}
string Troops::getName(){
return this->name;
}
void Troops::setAttr(int id,bool value){//1:混乱 2:断补 3:登陆中
if(id==1) this->in_confusion=value;
else if(id==2) this->no_supply=value;
else if(id==3) this->landing=value;
else return;
}
int Troops::getPl(){
return this->pl;
}
void rand_stat(){//TODO:机制还要改
vector<string> GERpool,USApool;
int cnt=0;
for(map<string,int>::iterator it=statics.begin();it!=statics.end();it++){
if(cnt<4&&(*it).second<=turn) USApool.push_back((*it).first);
if(cnt>=4&&(*it).second<=turn) GERpool.push_back((*it).first);
cnt++;
}
GERstat.push_back(GERpool[dice(GERpool.size())-1]);
USAstat.push_back(USApool[dice(USApool.size())-1]);
#if DEBUG
cout<<"德军新增战术卡:"<<GERstat.back()<<endl;
cout<<"盟军新增战术卡:"<<USAstat.back()<<endl;
cout<<"德军全部战术卡:";
for(int i=0;i<GERstat.size();i++){cout<<GERstat[i]<<" ";}
cout<<endl;
cout<<"盟军全部战术卡:";
for(int i=0;i<USAstat.size();i++){cout<<USAstat[i]<<" ";}
cout<<endl;
#endif
}
int battle(Troops atk,Troops def){//0:战败 1:战平 2:战胜
//TODO:多打一
system("cls");
cout<<"注意:battle函数内还有不少bug和未完成的内容"<<endl;
pair<int,int> posatk=atk.getPos(),posdef=def.getPos();
int realatk=atk.atk,realdef=def.def;
int platk=atk.pl,pldef=def.pl;//盟军:0,1 德军:2,3
#if !PRE_RELEASE
//询问进攻方是否使用战术卡
if(platk>1&&GERstat.size()>0){
cout<<"以下战术卡可供使用:"<<endl;
for(int i=0;i<GERstat.size();i++){
cout<<i<<" - "<<GERstat[i]<<endl;
}
}
if(platk<=1&&USAstat.size()>0){
}
//询问防守方是否使用战术卡
if(pldef>1&&GERstat.size()>0){
}
if(pldef<=1&&USAstat.size()>0){
}
#ifdef MAYBE_THERE_IS_ONE_DAY_I_CAN_BE_DEFINED
cout<<"HOW OLD ARE YOU"<<endl;
#endif
#else
cout<<"战术卡部分没做好,暂时跳过"<<endl;
#endif
//计算数值
cout<<"部队减员情况还没算上"<<endl;
if(types[posdef.first][posdef.second]==2) realdef+=1;
else if(types[posdef.first][posdef.second]==3) realdef+=2;
if(states[posdef].getCity()==1) realdef+=1;
else if(states[posdef].getCity()==2) realdef+=2;
if(states[posdef].getFort()) realdef+=2;
if(atk.landing) realatk=realatk/2+3;
for(int i=0;i<rivers[posatk].size();i++){
if(rivers[posatk][i]==posdef){
realatk=round(realatk/2.0);
break;
}
}
//TODO:战术卡部分
//展示预计数值(可取消战斗)
char accept=' ';
cout<<"预计情况:"<<endl;
cout<<"进攻方"<<left<<setw(10)<<atk.name<<left<<setw(5)<<realatk<<"攻击"<<endl;
cout<<"防御方"<<left<<setw(10)<<def.name<<left<<setw(5)<<realdef<<"防御"<<endl;
cout<<"确认进攻?(y/n):";
do{
accept=getchar_kick_others(1)[0];
cout<<endl;
}while (!(accept=='n'||accept=='y'));
if(accept=='n') return 1;
//战斗判定
int dmg=0,randomres=0;
cout<<"========================双方交火中========================"<<endl;
//进攻方输出
for(int i=1;i<=realatk;i++){
randomres=dice(6);
if(randomres>=5) dmg++;
#if DEBUG
if(i==1) cout<<"进攻方随机数:";
cout<<randomres<<" ";
if(i==realatk) cout<<endl;
#endif
}
//防御方输出
for(int i=1;i<=realdef;i++){
randomres=dice(6);
if(randomres>=5) dmg--;
#if DEBUG
if(i==1) cout<<"防御方随机数:";
cout<<randomres<<" ";
if(i==realdef) cout<<endl;
#endif
}
//结算
if(dmg>0){
cout<<"进攻方造成"<<dmg<<"点伤害"<<endl;
//防守方:撤退与追击判定
return 2;
}
else if(dmg<0){
dmg*=-1;
cout<<"防御方造成"<<dmg<<"点伤害"<<endl;
//进攻方:仅撤退判定
return 0;
}
else{
cout<<"未造成有效伤害"<<endl;
return 1;
}
}
void set_support(string troop_name,int pl){//让拥有troop_name的部队进场,需要指定阵营(0:德军(德装的增援其实两边都可以去),1:英军,2:美军(这两个必须在指定海滩尝试登陆),3:给开局的两支德装用的)
int tx,ty,op;
if(pl==0){
#ifdef MAYBE_THERE_IS_ONE_DAY_I_CAN_BE_DEFINED
cout<<"德军直接部署到英伦三岛,北美大陆,高 堡 奇 人"<<endl;
#endif
}
if(pl==1){
vector<pair<int,int>> choices={{12,11},{12,12},{14,14}};
cout<<"0 - 黄金海滩"<<endl;
cout<<"1 - 朱诺海滩"<<endl;
cout<<"2 - 宝剑海滩"<<endl;
cout<<"输入想要增援的地点序号:";
cin>>op;
while(!(0<=op&&op<=2)){
cout<<endl<<"无效选项,请重新输入:";
cin>>op;
}
cout<<endl<<"尝试登陆...";
if(dice(6)>1){
for(int i=0;i<ENG.size();i++){
if(ENG[i].getName()==troop_name){
if(states[{tx,ty}].getTroop()!=NULL&&states[{tx,ty}].getCtrl()==1){
int res=battle(ENG[i],*states[{tx,ty}].getTroop());
if(res==2){
cout<<"登陆成功."<<endl;
#if DEBUG
debug_print_troop_info(ENG[i]);
#endif
return;
}
else break;
}
ENG[i].setPos(tx,ty);
cout<<"登陆成功."<<endl;
#if DEBUG
debug_print_troop_info(ENG[i]);
#endif
return;
}
}
cout<<"登陆失败."<<endl;
return;
}
else{
cout<<"登陆失败."<<endl;
return;
}
}
if(pl==2){
vector<pair<int,int>> choices={{7,6},{9,8}};
if(global_flag["flag_can_land_on_cherbourg"]) choices.push_back({2,2});
cout<<"0 - 犹他海滩"<<endl;
cout<<"1 - 奥马哈海滩"<<endl;
if(global_flag["flag_can_land_on_cherbourg"]) cout<<"2 - 瑟堡"<<endl;
cout<<"输入想要增援的地点序号:";
cin>>op;
while(!(0<=op&&op<=2)){
cout<<endl<<"无效选项,请重新输入:";
cin>>op;
}
cout<<endl<<"尝试登陆...";
if(dice(6)>1){
for(int i=0;i<USA.size();i++){
if(USA[i].getName()==troop_name){
USA[i].setAttr(3,1);
if(states[{tx,ty}].getTroop()!=NULL&&states[{tx,ty}].getCtrl()==1){
int res=battle(USA[i],*states[{tx,ty}].getTroop());
if(res==2){
cout<<"登陆成功."<<endl;
#if DEBUG
debug_print_troop_info(USA[i]);
cout<<"这里的坐标不对,是因为正常情况会追击过去,但我没写完"<<endl;
#endif
return;
}
else break;
}
USA[i].setPos(tx,ty);
cout<<"登陆成功."<<endl;
#if DEBUG
debug_print_troop_info(USA[i]);
#endif
return;
}
}
cout<<"登陆失败."<<endl;
return;
}
else{
cout<<"登陆失败."<<endl;
return;
}
}
if(pl==3){
cout<<"输入"<<troop_name<<"的位置(用空格隔开):";
cin>>tx>>ty;
while(!(9<=ty&&ty<=15&&10<=tx&&tx<=21&&types[tx][ty]!=6&&types[tx][ty]!=0)){
cout<<endl<<"无效位置,请重新输入:";
cin>>tx>>ty;
}
for(int i=0;i<GERP.size();i++){
if(GERP[i].getName()==troop_name){
GERP[i].setPos(tx,ty);
#if DEBUG
debug_print_troop_info(GERP[i]);
#endif
return;
}
}
}
}
void welcome(){
system("title 霸王行动:诺曼底登陆1944战棋电子移植版");
cout<<"版本:"<<VERSION<<endl;
cout<<"编译日期:"<<__DATE__<<" "<<__TIME__<<endl;
cout<<"作者:"<<"Woding the Insider"<<endl;
cout<<"联系方式:"<<endl<<" Teams:[email protected](同时也是邮箱)"<<endl;
//PS:不会写GUI(qwq)
cout<<"本游戏仍然处于早期测试,有意见和想法联系可以上面邮箱awa"<<endl;
cout<<"更新日志在changelog.txt里~"<<endl;
system("pause");
system("cls");
}
void rollpl(vector<vector<Troops>::iterator> &list){
list.push_back(ENG.begin());
vector<vector<Troops>::iterator> pool={USA.begin(),GER7.begin(),GERP.begin()};
for(int i=pool.size();i>0;i=pool.size()){
int res=dice(i)-1;
list.push_back(pool[res]);
for(vector<vector<Troops>::iterator>::iterator it=pool.begin();it!=pool.end();it++){
if(pool[res]==*it){
pool.erase(it);
break;
}
}
}
}
int score_chk(){//0:对局继续 1:德军胜 2:盟军胜 3:平局
int score=0;
for(map<pair<int,int>,State>::iterator it=states.begin();it!=states.end();it++){
int state_score=(*it).second.getScore();
if(state_score>0&&(*it).second.getCtrl()==2){
score+=state_score;
}
}
if(turn==10){
if(score>14) return 2;
else if(score<14) return 1;
else return 3;
}
else{
if(score>=16) return 2;
else return 0;
}
}
int main(){
wcout.imbue(locale("chs"));
welcome();
cout<<"游戏初始化中..."<<endl;
init_info();
init_troops();
init_stat();
init_flags();
srand(time(nullptr));
init_states();
init_road();
#if !PRE_RELEASE
//TODO:允许更改指挥官名称
set_support("德装/86",3);
set_support("德装/1SS",3);
while(turn<=10){
//TODO:写一个输出地图的函数
if(turn%3==0) allies_support_point+=3;
if(turn==3) axis_forts+=2;
//战术卡
rand_stat();
//增援
//要塞(德军)
if(axis_forts>0){
char op='n';
//询问是否放置堡垒
do{
cout<<"德军是否放置堡垒?(剩余堡垒:"<<axis_forts<<")(y/n):";
op=getchar_kick_others(1)[0];
cout<<endl;
}while(!(op=='y'||op=='n'));
if(op=='y'){
int tx,ty;
do{
cout<<"请指定堡垒的放置位置(坐标):";
cin>>tx>>ty;
cout<<endl;
}while(!(type[tx][ty]!=0&&type[tx][ty]!=6&&states[{tx,ty}].second.getCtrl()==1));
states[{tx,ty}].second.setFort(1);
axis_forts--;
}
}
//抽签决定顺序
vector<vector<Troops>::iterator> pllist;
rollpl(pllist);
//行动
//清除混乱标记
for(int i=0;i<pllist.size();i++){
for(int i=0;i<ENG.size();i++){
ENG[i].setAttr(1,false);
}
for(int i=0;i<USA.size();i++){
USA[i].setAttr(1,false);
}
for(int i=0;i<GER7.size();i++){
GER7[i].setAttr(1,false);
}
for(int i=0;i<GERP.size();i++){
GERP[i].setAttr(1,false);
}
}
//检查补给
//整理阶段
int winres=score_chk();
if(winres>0){
system("cls");
//盟军胜利
if(winres==2){
cout<<"盟军胜利"<<endl;
cout<<allies_victory_message<<endl;
}
//德军胜利
else if(winres==1){
cout<<"德军胜利"<<endl;
cout<<axis_victory_message<<endl;
}
//平局
else{
cout<<"僵局"<<endl;
cout<<stalemate_message<<endl;
}
//输出结算信息
}
turn++;
}
#endif
#if PRE_RELEASE
char dbg_op;
debug_console_message();
while(true){
cout<<"输入序号以选择:";
dbg_op=getchar_kick_others(1)[0];
if(dbg_op=='0') debug_console_message();
if(dbg_op=='1'){
debug_state_message();
while(true){
char state_dbg_op=' ';
cout<<"输入序号以选择:";
state_dbg_op=getchar_kick_others(1)[0];
if(state_dbg_op=='0') debug_state_message();
if(state_dbg_op=='1'){
for(map<pair<int,int>,State>::iterator it=states.begin();it!=states.end();it++){
debug_print_state_info((*it).second);
cout<<"======================================================"<<endl;
}
}
if(state_dbg_op=='2'){
int tx,ty;
cout<<"请指定要打印的state坐标:";
cin>>tx>>ty;
if(0<=tx&&tx<=30&&0<=ty&&ty<=30&&types[tx][ty]!=6&&types[tx][ty]!=0){
debug_print_state_info(states[{tx,ty}]);
}
else{
cout<<"输入的坐标无效!"<<endl;
}
continue;
}
if(state_dbg_op=='q'){
debug_console_message();
break;
}
}
}
if(dbg_op=='2'){
debug_troop_message();
while(true){
char troop_dbg_op=' ';
cout<<"输入序号以选择:";
troop_dbg_op=getchar_kick_others(1)[0];
if(troop_dbg_op=='0') debug_troop_message();
if(troop_dbg_op=='1'){
for(int i=0;i<alltroops.size();i++){
for(int j=0;j<(*(alltroops[i])).size();j++){
debug_print_troop_info((*(alltroops[i]))[j]);
cout<<"======================================================"<<endl;
}
}
}
if(troop_dbg_op=='2'){
string tname;
cout<<"请指定要打印的troop名称:";
cin>>tname;
bool ok=0;
for(int i=0;i<alltroops.size();i++){
for(int j=0;j<(*(alltroops[i])).size();j++){
if((*(alltroops[i]))[j].getName()==tname){
debug_print_troop_info((*(alltroops[i]))[j]);
ok=1;
break;
}
}
if(ok) break;
}
if(!ok) cout<<"未找到对应名称的troop."<<endl;
continue;
}
if(troop_dbg_op=='q'){
debug_console_message();
break;
}
}
}
if(dbg_op=='3'){
char pl;
string troop_name;
cout<<"输入所属阵营和部队名称,分两行输入(先输入阵营)"<<endl;
cout<<"0:德军(德装的增援其实两边都可以去)(但这个我没做),1:英军,2:美军(这两个必须在指定海滩尝试登陆),3:给开局的两支德装用的"<<endl;
cout<<"不清楚部队名称可以输入q倒回去看troop信息"<<endl;
pl=getchar_kick_others(1)[0];
if(pl!='q') cin>>troop_name;
else if(!('0'<=pl&&pl<='3')){
cout<<"无效选项"<<endl;
continue;
}
set_support(troop_name,pl-'0');
}
if(dbg_op=='4'){
cout<<"已知bug:抽到的卡能反复抽,没有写用卡的代码导致卡的最低有效回合永远是1"<<endl;
rand_stat();
}
if(dbg_op=='5'){
#ifdef MAYBE_THERE_IS_ONE_DAY_I_CAN_BE_DEFINED
cout<<"我好看吗?TODO"<<endl;
#endif
int tapl,tdpl,tax,tay,tdx,tdy;
string aname,dname;
cout<<"测试登陆战去测试增援里弄"<<endl;
cout<<"请依次输入:进攻方阵营(不清楚的看Troops信息,下同),防守方阵营,进攻方名称,防守方名称,进攻方位置,防守方位置,以空格或换行隔开:"<<endl;
tapl=getchar_kick_others(1)[0]-'0';
tdpl=getchar_kick_others(1)[0]-'0';
aname=getchar_kick_others(MAX_NAME_LENGTH);
dname=getchar_kick_others(MAX_NAME_LENGTH);
tax=getchar_kick_others(1)[0]-'0';
tay=getchar_kick_others(1)[0]-'0';
tdx=getchar_kick_others(1)[0]-'0';
tdy=getchar_kick_others(1)[0]-'0';
int ti,tj;
for(ti=0;ti<(*(alltroops[tapl])).size();ti++){
if((*(alltroops[tapl]))[ti].getName()==aname){
break;
}
}
for(tj=0;tj<(*(alltroops[tdpl])).size();tj++){
if((*(alltroops[tdpl]))[tj].getName()==dname){
break;
}
}
Troops tatk=(*(alltroops[tapl]))[ti],tdef=(*(alltroops[tdpl]))[tj];
tatk.setPos(tax,tay);
tdef.setPos(tdx,tdy);
battle(tatk,tdef);
}
//删除大段注释提高下效率
if(dbg_op=='6'){
cout<<"所有global flag状态如下:"<<endl;
for(map<string,bool>::iterator it=global_flag.begin();it!=global_flag.end();it++){
cout<<(*it).first<<":"<<bool_to_str((*it).second)<<endl;
cout<<"======================================================"<<endl;
}
}
if(dbg_op=='7'){
vector<vector<Troops>::iterator> pllist;
rollpl(pllist);
cout<<"顺序:"<<endl;
for(int i=0;i<pllist.size();i++){
cout<<players[(*pllist[i]).getPl()]<<" ";
}
cout<<endl;
}
if(dbg_op=='8'){
#ifndef MAYBE_THERE_IS_ONE_DAY_I_CAN_BE_DEFINED
if(dice(100)<=5){
cout<<"#define MAYBE_THERE_IS_ONE_DAY_I_CAN_BE_DEFINED"<<endl;
cout<<"你能帮帮它吗(doge)"<<endl;
}
else cout<<"稍后会有\"好玩的东西\"..."<<endl;
#else
cout<<"TODO"<<endl;
#endif
}
if(dbg_op=='9'){
char option_commander_index;
wcout<<L"0 - 盟军:"<<allies_commander<<endl;
wcout<<L"1 - 德军:"<<axis_commander<<endl;
cout<<"请输入要更改的名称序号:";
option_commander_index=getchar_kick_others(1)[0];
if(option_commander_index=='0'){
cout<<"请输入更改后的名称:";
allies_commander=string2wstring(getchar_kick_others(MAX_NAME_LENGTH));
}
else if(option_commander_index=='1'){
cout<<"请输入更改后的名称:";
axis_commander=string2wstring(getchar_kick_others(MAX_NAME_LENGTH));
}
else{
cout<<"序号无效!"<<endl;
}
}
if(dbg_op=='A'){
cout<<"盟军胜利:"<<endl;
wcout<<allies_victory_message<<endl;
cout<<"德军胜利:"<<endl;
wcout<<axis_victory_message<<endl;
cout<<"僵局"<<endl;
wcout<<stalemate_message<<endl;
}
if(dbg_op=='q'){
break;
}
}
#endif
return 0;
}
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
C++
1
https://gitee.com/insiderwoding/normandy-landing-battle-chess.git
[email protected]:insiderwoding/normandy-landing-battle-chess.git
insiderwoding
normandy-landing-battle-chess
诺曼底登陆战棋
master

搜索帮助