Initial commit on develop branch

This commit is contained in:
2026-04-13 15:23:38 +03:30
commit d9c97eaae4
+549
View File
@@ -0,0 +1,549 @@
#include<iostream>
#include<conio.h>
#include<cstdlib>
#include<ctime>
#include<string>
#include<algorithm>
#include<fstream>
#include<windows.h>
using namespace std;
struct game_history{
string p1_name;
string p2_name;
int black_score;
int white_score;
string winner_name;
string time;
};
game_history game_h[100];
int cu =0;
//تعداد بازی های انجام شده
void enter_data();
void add_data(game_history game_history);
void report_data();
void load_data();
void save_data();
const int BOARD_SIZE = 8;
const char EMPTY = '-';
const char BLACK = 'B';
const char WHITE = 'W';
char board [BOARD_SIZE][BOARD_SIZE];
struct coordinate{
int r;
int c;
};
void Initialize_Board(){
for (int r=0 ; r<BOARD_SIZE ; r++){
for(int c=0 ; c<BOARD_SIZE ; c++){
board[r][c]=EMPTY;
}
}
board[3][3] = WHITE;
board[4][4] = WHITE;
board[3][4] = BLACK;
board[4][3] = BLACK;
}
void clear_screen(){
system("cls");
}
void print_board(char current_player , const bool valid_moves[BOARD_SIZE][BOARD_SIZE] ,int cursor_r ,int cursor_c){
cout << "\n ~~~~~~~~~~~~~~~~~~~~ " << endl;
cout << "turn :" << (current_player == BLACK ? "B" : "W") << endl;
cout << " ";
for(int c=0 ; c<BOARD_SIZE ; c++){
cout << " " << c+1;
}
cout << endl;
for (int r=0; r<BOARD_SIZE; r++){
cout << r+1 << (r<9 ? " " : " ");
for(int c=0 ; c<BOARD_SIZE ; c++){
char display_char = board[r][c];
if(valid_moves[r][c]){
display_char ='*';
}
if(r == cursor_r && c == cursor_c){
if(display_char == EMPTY || display_char == '*'){
display_char = (current_player== BLACK ? 'b' : 'w');
}
}
cout << " " << display_char;
}
cout << " |" <<endl;
}
cout << "~~~~~~~~~~~~~~~~~~~~" << endl;
}
bool is_valid_move(int r , int c , char player , char opponent){
if ( r<0 || r>= BOARD_SIZE || c<0 || c>= BOARD_SIZE || board[r][c] != EMPTY) return false;
int direct_r [] = {0 , 1 , 1 , 1 , 0 , -1 , -1 , -1 };
int direct_c [] = {1 , 1 , 0 , -1 , -1 , -1 , 0 , 1 };
for (int i = 0; i < 8; i++){
int next_r = r+ direct_r[i];
int next_c = c+ direct_c[i];
bool found_opponent = false;
while(next_r>=0 && next_r<BOARD_SIZE && next_c>=0 && next_r<BOARD_SIZE){
if(board[next_r][next_c] == opponent){
found_opponent = true;
}
else if(board[next_r][next_c] == player){
if(found_opponent) return true;
break;
}
else if(board[next_r][next_c] == EMPTY) break;
next_r += direct_r[i];
next_c += direct_c[i];
}
}
return false;
}
void get_valid_moves(char player , char opponent , bool valid_moves[BOARD_SIZE][BOARD_SIZE]){
for (int r= 0; r < BOARD_SIZE; r++){
for (int c = 0; c < BOARD_SIZE; c++){
valid_moves[r][c] = is_valid_move(r ,c , player , opponent);
}
}
}
int make_move(int r, int c , char player , char opponent){
board[r][c] = player;
int flipped_count = 0;
int direct_r [] = {0 , 1 , 1 , 1 , 0 , -1 , -1 , -1 };
int direct_c [] = {1 , 1 , 0 , -1 , -1 , -1 , 0 , 1 };
for (int i = 0; i < 8; i++){
int next_r = r + direct_r[i];
int next_c = c + direct_c[i];
bool found_opponent = false;
int temp_r = next_r;
int temp_c = next_c;
while(temp_r>=0 && temp_r<BOARD_SIZE && temp_c>=0 && temp_c < BOARD_SIZE){
if (board[temp_r][temp_c] == opponent){
found_opponent = true;
}
else if(board[temp_r][temp_c] == player){
if(found_opponent){
int flip_r = next_r;
int flip_c = next_c;
while(flip_r != temp_r || flip_c !=temp_c){
if(board[flip_r][flip_c] == opponent){
board[flip_r][flip_c] = player;
flipped_count++;
}
if(flip_r<temp_r) flip_r++;
else if(flip_r>temp_r) flip_r--;
if(flip_c<temp_c) flip_c++;
else if(flip_c>temp_c) flip_c--;
}
}
break;
}
else if(board[temp_r][temp_c] == EMPTY){
break;
}
if(temp_r < temp_r +direct_r[i]) temp_r++;
else if(temp_r > temp_r +direct_r[i]) temp_r--;
if(temp_c < temp_c +direct_c[i]) temp_c++;
else if(temp_c > temp_c +direct_c[i]) temp_c--;
}
}
return flipped_count;
}
void run_game_flow(const string & player1_name ,const string &player2_name, bool is_single_player ){
Initialize_Board();
char current_player =BLACK;
string p1_name = player1_name;
string p2_name = player2_name;
string time;
int current_row = BOARD_SIZE/2-1;
int current_col = BOARD_SIZE/2-1;
bool valid_moves [BOARD_SIZE][BOARD_SIZE] = {false};
get_valid_moves(current_player , (current_player == BLACK ? WHITE : BLACK) , valid_moves);
bool initial_cursor_set = false;
for (int r= 0; r < BOARD_SIZE; r++){
for (int c = 0; c < BOARD_SIZE; c++){
if(valid_moves[r][c]){
current_row = r;
current_col = c;
initial_cursor_set = true;
}
}
}
while(true){
char opponent =(current_player == BLACK ? WHITE : BLACK);
get_valid_moves(current_player , opponent , valid_moves);
int black_score =0;
int white_score =0;
bool current_can_move = false;
for (int r= 0; r < BOARD_SIZE; r++){
for (int c = 0; c < BOARD_SIZE; c++){
if(board[r][c]== BLACK) black_score++;
if(board[r][c]== WHITE) white_score++;
if(valid_moves[r][c]) current_can_move = true;
}
}
bool temp_moves[BOARD_SIZE][BOARD_SIZE] ={false};
get_valid_moves(opponent, current_player , temp_moves);
bool opponent_can_move = false;
for (int r= 0; r < BOARD_SIZE; r++){
for (int c = 0; c < BOARD_SIZE; c++){
if(temp_moves[r][c]){
opponent_can_move =true;
break;
}
}
if(opponent_can_move) break;
}
if(!current_can_move && !opponent_can_move){
clear_screen();
cout << "\n ~~~~~The End of Game~~~~~"<<endl;
cout <<" final black score : ( " << black_score <<" )"<<endl;
cout <<" final white score : ( " << white_score <<" )"<<endl;
if(black_score > white_score) cout <<"The winner : " << p1_name << endl;
else if(white_score > black_score) cout << "The winner : " << p2_name<<endl;
else if(white_score == black_score) cout << "it is a draw!" <<endl;
game_history gh;
gh.p1_name = p1_name;
gh.p2_name = p2_name;
gh.black_score = black_score;
gh.white_score = white_score;
gh.winner_name = (black_score>white_score) ? p1_name : (black_score>white_score) ? p2_name : "Draw";
gh.time = time;
add_data(gh);
cout << "\n press Enter to return to meno ...";
getch();
break;
}
if(!current_can_move){
cout << current_player <<"pass!" << endl;
current_player = opponent;
continue;
}
clear_screen();
print_board(current_player, valid_moves ,current_row , current_col);
cout <<"current black_score: "<< black_score <<endl;
cout <<"current white_score: "<< white_score <<endl;
string current_name = (current_player == BLACK? p1_name : p2_name);
int row = -1 , col = -1;
bool valid_input = false;
if(is_single_player && current_player == WHITE){
cout << "Bot is thinking ... "<< endl;
coordinate possible_moves[BOARD_SIZE*BOARD_SIZE];
int move_count_found = 0;
for (int r= 0; r < BOARD_SIZE; r++){
for (int c = 0; c < BOARD_SIZE; c++){
if(valid_moves[r][c]){
possible_moves[move_count_found].r = r;
possible_moves[move_count_found].c = c;
move_count_found++;
}
}
}
if(move_count_found > 0){
int index = rand() % move_count_found;
row = possible_moves[index].r;
col = possible_moves[index].c;
valid_input = true;
}
}
else{
cout <<"Turn : "<< current_name <<endl ;
while(!valid_input){
cout << "enter move( W / A / S / D , P/SPACE/Enter to place , Q to quit) : ";
char input_char;
input_char = getch();
input_char = toupper(input_char);
if(input_char == 'W' || input_char == 'A' || input_char == 'S' || input_char == 'D'){
int temp_row = current_row;
int temp_col = current_col;
switch (input_char){
case 'W':
if (current_row > 0) temp_row--;
break;
case 'S':
if(current_row < BOARD_SIZE-1) temp_row++;
break;
case 'A':
if(current_col > 0) temp_col--;
break;;
case 'D':
if(current_col < BOARD_SIZE-1) temp_col++;
break;
}
current_row = temp_row;
current_col = temp_col;
clear_screen();
print_board(current_player , valid_moves , current_row , current_col);
cout << "current black_score : " << black_score << endl;
cout << "current white_score : " << white_score << endl;
cout << " Turn : " <<current_name << endl;
}
else if(input_char == 'P' || input_char == 13 || input_char == 32){ // 13=Enter , 32=space
row = current_row;
col = current_col;
if(valid_moves[row][col]) valid_input = true;
}
else if (input_char == 'Q'){
cout <<"returning to meno ..."<<endl;
return;
}
}
}
if (valid_input){
make_move(row , col , current_player ,opponent);
current_player = opponent;
clear_screen();
print_board(current_player , valid_moves , current_row , current_col);
cout << "current black_score : " << black_score << endl;
cout << "current white_score : " << white_score << endl;
cout << " Turn : " <<current_name << endl;
}
}
}
void display_menu(){
cout << "~~~~~ menu ~~~~~"<< endl;
cout << "choose one option please" << endl << "~~~~~~~~~~~~~~~~~~~~~"<<endl;
cout << "1.New Game" << endl;
cout << "2.Help" << endl;
cout << "3.Game History" << endl;
cout << "4.Enter Game Data" << endl;
cout << "5.Exit" << endl;
cout << " choice : ";
}
void handle_new_game(){
string p1_name , p2_name ;
int choice;
cout << " \n please choose :"<<endl;
cout << "1.tow_player"<<endl;
cout << "2.single player" << endl;
cout << " choice : ";
cin >> choice;
if(choice==1){
cout << "p1.name : ";
cin >> p1_name;
cout << " \n p2.name : ";
cin >> p2_name;
run_game_flow(p1_name, p2_name ,false);
}
else{
cout << "p.name : ";
cin >> p1_name;
run_game_flow(p1_name , "Bot" , true);
}
}
void handle_help(){
cout << "\n=== HOW TO PLAY OTHELLO ===" << endl;
cout << "\nOBJECTIVE:" << endl;
cout << "Have more discs of your color than your opponent at the end." << endl;
cout << "\nRULES:" << endl;
cout << "1. Black always starts first" << endl;
cout << "2. Place your disc so that it traps opponent's discs between your discs" << endl;
cout << "3. All trapped opponent discs flip to your color" << endl;
cout << "4. You can trap discs in any direction: horizontal, vertical, diagonal" << endl;
cout << "5. If you have no valid moves, you must pass" << endl;
cout << "6. Game ends when both players have no valid moves" << endl;
cout << "\nCONTROLS:" << endl;
cout << "W - Move cursor up" << endl;
cout << "S - Move cursor down" << endl;
cout << "A - Move cursor left" << endl;
cout << "D - Move cursor right" << endl;
cout << "P - Place disc" << endl;
cout << "Q - Quit game" << endl;
cout << "\nBOARD SYMBOLS:" << endl;
cout << "B - Black disc" << endl;
cout << "W - White disc" << endl;
cout << "* - Valid move position" << endl;
cout << "b/w - Cursor position (empty cell)" << endl;
cout << "\nPress any key to return to menu...";
getch();
}
void load_data(){
ifstream file("data.text");
if(file.is_open()){
cu=0;
while (cu <100 && file >> game_h[cu].p1_name && file >> game_h[cu].p2_name && file >> game_h[cu].black_score && file >> game_h[cu].white_score && file >> game_h[cu].time){
cu++;
}
}
file.close();
}
void save_data(){
ofstream file("data.text");
if(file.is_open()){
for (int i = 0; i < cu; i++){
file << game_h[i].p1_name <<" "<<game_h[i].p2_name << " " << game_h[i].black_score << " " << game_h[i].white_score << " " << game_h[i].time << endl;
}
file.close();
}
}
void enter_data(){
game_history gh;
cout << "~~~~~~~~~~~ Enter Data~~~~~~~~~~~\n";
cout << "Enter Black name: ";
cin >> gh.p1_name;
cout << "Enter White name: ";
cin >> gh.p2_name;
cout << "Enter Black score : ";
cin >> gh.black_score;
cout << "Enter White score : ";
cin >> gh.white_score;
if(gh.black_score > gh.white_score) gh.winner_name = gh.p1_name;
else if(gh.white_score < gh.black_score) gh.winner_name = gh.p2_name;
else gh.winner_name = "Draw!";
cout << "Enter the time of the game : ";
cin >> gh.time;
add_data(gh);
getch();
}
void report_data(){
cout << "\n~~~~~~~~~~~Data~~~~~~~~~~~\n";
if(cu ==0) cout <<" no game history available";
else{
for (int i = 0; i < cu; i++){
game_history gah = game_h[i];
cout << "\n ~~~~~~~~~~~~~~ The History ~~~~~~~~~~~~~~";
cout << "p1_name : " << gah.p1_name <<endl;
cout << "p2_name : " << gah.p2_name <<endl;
cout << "black_score : " << gah.black_score << endl;
cout << "white_score : " << gah.white_score << endl;
cout << "date : " <<gah.time << endl;
}
}
getch();
}
void add_data(game_history gh){
game_h[cu] = gh;
cu++;
save_data();
}
int main(){
srand(static_cast<unsigned int>(time(nullptr)));
load_data();
int choice;
bool running = true;
while(running){
display_menu();
cin >> choice;
switch (choice)
{
case 1:
handle_new_game();
break;
case 2:
handle_help();
break;
case 3:
report_data();
break;
case 4:
enter_data();
break;
case 5:
running = false;
break;
}
}
return 0;
}