#include <iostream>
#include <conio.h>
#include <windows.h>
#include <cstdlib>
#include <ctime>
#include <cmath>
using namespace std;
const int MAP_SIZE=10;
const int DAMAGE=10;
const int MAX_HEALTH=100;
const int REFRESH_MS=150;
HANDLE hConsole;
COORD cursorPos;
void gotoxy(int x,int y){
    cursorPos.X=x;
    cursorPos.Y=y;
    SetConsoleCursorPosition(hConsole,cursorPos);
}
void hideCursor(){
    CONSOLE_CURSOR_INFO cursorInfo;
    GetConsoleCursorInfo(hConsole,&cursorInfo);
    cursorInfo.bVisible=false;
    SetConsoleCursorInfo(hConsole,&cursorInfo);
}
struct Player{
    int x,y;
    int health;
    char symbol;
    char key_up,key_down,key_left,key_right,key_attack;
};
void initPlayer(Player &p,char sym,char up,char down,char left,char right,char attack){
    p.symbol=sym;
    p.key_up=up;
    p.key_down=down;
    p.key_left=left;
    p.key_right=right;
    p.key_attack=attack;
    p.health=MAX_HEALTH;
}
bool isAdjacent(const Player &a,const Player &b){
    return abs(a.x-b.x)+abs(a.y-b.y)==1;
}
void tryMove(Player &p,int dx,int dy,const Player &other){
    int nx=p.x+dx;
    int ny=p.y+dy;
    if(nx<0||nx>=MAP_SIZE||ny<0||ny>=MAP_SIZE)return;
    if(nx==other.x&&ny==other.y)return;
    p.x=nx;
    p.y=ny;
}
void tryAttack(Player &attacker,Player &defender){
    if(isAdjacent(attacker,defender)){
        defender.health-=DAMAGE;
        if(defender.health<0)defender.health=0;
    }
}
void draw(const Player &p1,const Player &p2){
    gotoxy(0,0);
    cout<<" ";
    for(int j=0;j<MAP_SIZE;j++)cout<<" "<<j%10;
    cout<<"\n";
    for(int i=0;i<MAP_SIZE;i++){
        cout<<i%10<<" ";
        for(int j=0;j<MAP_SIZE;j++){
            if(i==p1.x&&j==p1.y)cout<<p1.symbol<<" ";
            else if(i==p2.x&&j==p2.y)cout<<p2.symbol<<" ";
            else cout<<". ";
        }
        cout<<"\n";
    }
    cout<<"\n玩家1 (1) HP: "<<p1.health<<"/"<<MAX_HEALTH;
    cout<<"  位置 ("<<p1.x<<","<<p1.y<<")\n";
    cout<<"玩家2 (2) HP: "<<p2.health<<"/"<<MAX_HEALTH;
    cout<<"  位置 ("<<p2.x<<","<<p2.y<<")\n";
    cout<<"\n玩家1移动: W/A/S/D   攻击: Q\n";
    cout<<"玩家2移动: U/H/J/K   攻击: I\n";
    cout<<"刷新间隔 "<<REFRESH_MS<<"ms,按住按键可连续移动。\n";
}
bool gameOver(const Player &p1,const Player &p2){
    return p1.health<=0||p2.health<=0;
}
int main(){
    srand((unsigned)time(NULL));
    hConsole=GetStdHandle(STD_OUTPUT_HANDLE);
    hideCursor();
    Player p1,p2;
    initPlayer(p1,'1','w','s','a','d','q');
    initPlayer(p2,'2','u','j','h','k','i');
    do{
        p1.x=rand()%MAP_SIZE;
        p1.y=rand()%MAP_SIZE;
        p2.x=rand()%MAP_SIZE;
        p2.y=rand()%MAP_SIZE;
    }while(p1.x==p2.x&&p1.y==p2.y);
    cout<<"双人实时对战开始!\n";
    cout<<"地图 "<<MAP_SIZE<<"x"<<MAP_SIZE<<"\n";
    cout<<"血量 "<<MAX_HEALTH<<",每次攻击伤害 "<<DAMAGE<<"\n";
    cout<<"按任意键开始...";
    _getch();
    while(!gameOver(p1,p2)){
        while(_kbhit()){
            char ch=_getch();
            if(ch>='A'&&ch<='Z')ch+=32;
            if(ch==p1.key_up)tryMove(p1,-1,0,p2);
            else if(ch==p1.key_down)tryMove(p1,1,0,p2);
            else if(ch==p1.key_left)tryMove(p1,0,-1,p2);
            else if(ch==p1.key_right)tryMove(p1,0,1,p2);
            else if(ch==p1.key_attack)tryAttack(p1,p2);
            else if(ch==p2.key_up)tryMove(p2,-1,0,p1);
            else if(ch==p2.key_down)tryMove(p2,1,0,p1);
            else if(ch==p2.key_left)tryMove(p2,0,-1,p1);
            else if(ch==p2.key_right)tryMove(p2,0,1,p1);
            else if(ch==p2.key_attack)tryAttack(p2,p1);
        }
        draw(p1,p2);
        Sleep(REFRESH_MS);
    }
    draw(p1,p2);
    cout<<"\n";
    if(p1.health<=0&&p2.health<=0)cout<<"平局!\n";
    else if(p1.health<=0)cout<<"玩家2 获胜!\n";
    else cout<<"玩家1 获胜!\n";
    cout<<"按任意键退出...";
    _getch();
    return 0;
}