From 9136a124f50d8ee73154ad75c86a04493e81fc55 Mon Sep 17 00:00:00 2001 From: odilsonjs Date: Wed, 15 Nov 2023 11:25:05 -0500 Subject: [PATCH 1/2] Fix bug with error messages --- lib/game.rb | 42 +++++++++++++++++++++++++----------------- 1 file changed, 25 insertions(+), 17 deletions(-) diff --git a/lib/game.rb b/lib/game.rb index d852f66..6a8ff03 100644 --- a/lib/game.rb +++ b/lib/game.rb @@ -36,6 +36,7 @@ def human_vs_human if position_of_the_choosed_piece.length != 2 puts "Invalid input".light_red puts "Your position should be two characters length".light_blue + sleep(3) redo elsif (("a".."h").to_a.include?(position_of_the_choosed_piece[0]) && ("1".."8").to_a.include?(position_of_the_choosed_piece[1])) @@ -44,12 +45,19 @@ def human_vs_human @chessboard.active_piece = @chessboard.data[array_index_positions[0]][array_index_positions[1]] if @chessboard.active_piece.nil? - puts "This square doesn't have any #{current_player.piece_color} piece \nPlease try again" - @chessboard.active_piece = nil + puts "This square doesn't have any #{current_player.piece_color} piece \nPlease try again".light_blue + sleep(3) redo elsif @chessboard.active_piece.color != current_player.piece_color puts "WARNING, You can't move this piece".light_red @chessboard.active_piece = nil + sleep(3) + redo + + elsif @chessboard.active_piece.allowed_moves.empty? + puts "You can't move this piece anywhere".light_blue + puts "Please choose another one".light_blue + sleep(3) redo else @@ -106,17 +114,20 @@ def human_vs_human break else puts "WARNING, you can't move this piece there".light_red + sleep(3) redo end else puts "Invalid input".light_red puts "Your position should be composed of a letter between 'a' and 'h' and a digit between '1' and '8'".light_blue + sleep(3) redo end end end else puts "Your position should be composed of a letter between 'a' and 'h' and a digit between '1' and '8'".light_blue + sleep(3) redo end @@ -158,6 +169,7 @@ def human_vs_ai if position_of_the_choosed_piece.length != 2 puts "Invalid input".light_red puts "Your position should be two characters length".light_blue + sleep(3) redo elsif (("a".."h").to_a.include?(position_of_the_choosed_piece[0]) && ("1".."8").to_a.include?(position_of_the_choosed_piece[1])) @@ -166,12 +178,18 @@ def human_vs_ai @chessboard.active_piece = @chessboard.data[array_index_positions[0]][array_index_positions[1]] if @chessboard.active_piece.nil? - puts "This square doesn't have any #{current_player.piece_color} piece \nPlease try again" - @chessboard.active_piece = nil + puts "This square doesn't have any #{current_player.piece_color} piece \nPlease try again".light_blue + sleep(3) redo elsif @chessboard.active_piece.color != current_player.piece_color puts "WARNING, You can't move this piece".light_red @chessboard.active_piece = nil + sleep(3) + redo + elsif @chessboard.active_piece.allowed_moves.empty? + puts "You can't move this piece anywhere".light_blue + puts "Please choose another one".light_blue + sleep(3) redo else @@ -230,17 +248,20 @@ def human_vs_ai break else puts "WARNING, you can't move this piece there".light_red + sleep(3) redo end else puts "Invalid input".light_red puts "Your position should be composed of a letter between 'a' and 'h' and a digit between '1' and '8'".light_blue + sleep(3) redo end end end else puts "Your position should be composed of a letter between 'a' and 'h' and a digit between '1' and '8'".light_blue + sleep(3) redo end @@ -359,16 +380,3 @@ def convert(input) end end - -game = ChessGame.new -game.play_with_two_ai - -chessboard = ChessBoard.new - - - -# setup(chessboard) -# chessboard.active_piece = chessboard.data.dig(3, 3) -# p chessboard.active_piece.attack_moves -# p chessboard.active_piece.allowed_moves -# chessboard.display From 66f719799568799329bbcbe703ec619b29885b55 Mon Sep 17 00:00:00 2001 From: odilsonjs Date: Wed, 15 Nov 2023 20:10:10 -0500 Subject: [PATCH 2/2] Complete serialization feature A player can now save the game and play again later at the same state that he left off --- chessgame_data/Odil2023.txt | Bin 0 -> 1376 bytes chessgame_data/Odilson_Alexa.txt | Bin 0 -> 1393 bytes lib/game.rb | 259 +++++++++++++++++++++---------- main.rb | 34 ++-- serializable.rb | 25 +++ 5 files changed, 220 insertions(+), 98 deletions(-) create mode 100644 chessgame_data/Odil2023.txt create mode 100644 chessgame_data/Odilson_Alexa.txt create mode 100644 serializable.rb diff --git a/chessgame_data/Odil2023.txt b/chessgame_data/Odil2023.txt new file mode 100644 index 0000000000000000000000000000000000000000..abbd4ce0838bed9d4aff822827bc9a0d1448e6db GIT binary patch literal 1376 zcmZ`(%Wm5+5cHvtsfV2hTJ&-B7s$ztybvjh!pNa%;hPQuBNNdgwpNhj1pWI`6eUac z_DIiYcV>3I9~koG_gvTYPj%1>el4^1@rq~c)L`5vYqY9QoWP|w?bDXA=3K@hW$siYbOD_e8H9w; zO<;nL(9X;M&~7{vw9VZuP((>X;g&C=>|wvS5v3c&b+=fN8_=Y)G3~ZKqD>8rNmGMp z!c@B~Sp#o6EkS2G=8?p*y%C$0w{ADe9E5VO{^}~tj|WwxYjX~s><`QwnZn$m%_{n} zgME#K<=;qKDeZ5|;DmpYnJSxOrFUJkI`O)B#FziH^R{;=J~Q!UvkJGlI;hGn``5`C Z`j*Vjzq*gPk<-ankgliCyXo^j{s(zoOH=>= literal 0 HcmV?d00001 diff --git a/chessgame_data/Odilson_Alexa.txt b/chessgame_data/Odilson_Alexa.txt new file mode 100644 index 0000000000000000000000000000000000000000..06687d4177a8e0605637e0d39c17c63d1ae098ba GIT binary patch literal 1393 zcmaJ>O>dkq6yy-`&E})+rO9c30ZniA#Yt6Fs~nm}xp6=aYlWw z2{Yq)^Ty_#_()dYO3}7I_)a9`j1_9}gnYk6a@r%eYT=QPZF$GDBukJ44~Q=TS+NFN z=m6`?0|y)uu>vdHZ`R>c#ful0xZfYiN7j`hKk71rc}6ONIQ2mJeQr}L>3MW zOpSPnDl2_b_x!EaDlRxn9?}m6b^nXn0y*xrgfUUJWH3Q({U4Prou{%fdZBI0b6?s{ z`)4fSfhC|U(X3Re$+wXlfbQk3gig4_(JQLiFfv2X-sVi@ZHP1)yv+y`R0sYZsso>) zN0$-kOlR;!T4y>#r<-*iGg$c!bf&T0_mFrDR^P*Qj=|y^>6uZsgp2gtpw^~FWlK}z zJ&0|GG3m(Cv6=!!2d^S;KolY+F~dd;lg-+_RwpkfM^o`XVxO0X9k25*>AzpD7hk^0 zU-!P>=d7=mn?W@m0{O%W-gJk(*lI&^E)mJr4mhat)1|CE bUCP4V&Bmvn<=DEZ#Bbi;-OJe!yULuu^5#xd literal 0 HcmV?d00001 diff --git a/lib/game.rb b/lib/game.rb index 6a8ff03..1654d86 100644 --- a/lib/game.rb +++ b/lib/game.rb @@ -5,42 +5,78 @@ require 'colorize' class ChessGame + attr_accessor :option def initialize @chessboard = ChessBoard.new - + @option = "1" + @player_human_1 = nil + @player_human_2 = nil + @player_human_3 = nil + @player_ai_1 = nil + @player_ai_2 = nil + @player_ai_3 = nil end - def human_vs_human - puts "Player-1 What is your name?" - name1 = gets.chomp - player_1 = Player.new(name1, "white") - puts "Okay, #{player_1.name}, the white pieces have been assigned to you" - - puts "Player-2 What is your name?" - name2 = gets.chomp - player_2 = Player.new(name2, "black") + def play(option = @option) + @option = option + if option == "1" + human_vs_human + elsif option == "2" + human_vs_ai + else + ai_vs_ai + end + end - puts "Okay, #{player_2.name}, the black pieces have been assigned to you" - - setup(@chessboard) + def human_vs_human + if @player_human_1.nil? + puts "Player-1 What is your name?" + name1 = gets.chomp + @player_human_1 = Player.new(name1, "white") + + puts "Okay, #{@player_human_1.name}, the white pieces have been assigned to you" + end + + if @player_human_2.nil? + puts "Player-2 What is your name?" + name2 = gets.chomp + @player_human_2 = Player.new(name2, "black") + + puts "Okay, #{@player_human_2.name}, the black pieces have been assigned to you" + setup(@chessboard) + end - - current_player = player_1 + current_player = @player_human_1 do_break = false loop do @chessboard.display current_player.show_captured_piece puts "It's #{current_player.name}'s turn" puts "Choose the piece you want to move. eg(d1)" - position_of_the_choosed_piece = gets.chomp - if position_of_the_choosed_piece.length != 2 + answer_1 = gets.chomp + if answer_1 == "s" + puts "What is the name to save your progress on?" + name = gets.chomp + file = open("chessgame_data/#{name}.txt", 'w') + file.write Marshal.dump(self) + file.close + puts "Your progress has been saved!".light_green + return + elsif answer_1 == "q" + puts "Are you sure that you want to qui?[y/n]" + confirmation = gets.chomp + if confirmation == "y" + puts "You quit the game".light_red + return + end + elsif answer_1.length != 2 puts "Invalid input".light_red puts "Your position should be two characters length".light_blue sleep(3) redo - elsif (("a".."h").to_a.include?(position_of_the_choosed_piece[0]) && ("1".."8").to_a.include?(position_of_the_choosed_piece[1])) - array_index_positions = convert(position_of_the_choosed_piece) + elsif (("a".."h").to_a.include?(answer_1[0]) && ("1".."8").to_a.include?(answer_1[1])) + array_index_positions = convert(answer_1) @chessboard.active_piece = @chessboard.data[array_index_positions[0]][array_index_positions[1]] @@ -53,13 +89,13 @@ def human_vs_human @chessboard.active_piece = nil sleep(3) redo - + elsif @chessboard.active_piece.allowed_moves.empty? puts "You can't move this piece anywhere".light_blue puts "Please choose another one".light_blue sleep(3) redo - + else @chessboard.display puts "#{current_player.name}'s captured pieces:" @@ -67,17 +103,32 @@ def human_vs_human loop do puts "Choose the position you want to move your piece to" new_position = gets.chomp - if new_position.length != 2 + if new_position == "s" + puts "What is the name to save your progress on?" + name = gets.chomp + file = open("chessgame_data/#{name}.txt", 'w') + file.write Marshal.dump(self) + file.close + puts "Your progress has been saved!".light_green + return + elsif new_position == "q" + puts "Are you sure that you want to qui?[y/n]" + confirmation = gets.chomp + if confirmation == "y" + puts "You quit the game".light_red + return + end + elsif new_position.length != 2 puts "Invalid input".light_red puts "Your position should be two characters length".light_blue redo elsif (("a".."h").to_a.include?(new_position[0]) && ("1".."8").to_a.include?(new_position[1])) array_indexes_of_new_positions = convert(new_position) - + # Check if the position of the choosed piece is included inside the active_piece's attack_moves if @chessboard.active_piece.attack_moves.include?(array_indexes_of_new_positions) the_attacked_piece = @chessboard.data.dig(array_indexes_of_new_positions[0], array_indexes_of_new_positions[1]) - + if the_attacked_piece.class.name == "King" do_break = true puts "CHECKMATE".light_green @@ -85,26 +136,26 @@ def human_vs_human break end - - + + # Capture the enemy's piece @chessboard.remove(the_attacked_piece) the_attacked_piece.position = nil current_player.captured_pieces << the_attacked_piece - + #remove the active piece with old position @chessboard.remove(@chessboard.active_piece) - + # Add the active piece to the new position @chessboard.active_piece.position = array_indexes_of_new_positions @chessboard.add(@chessboard.active_piece) @chessboard.active_piece = nil break - + # Check if the position of the choosed piece is included inside the active_piece's allowed_moves elsif @chessboard.active_piece.allowed_moves.include?(array_indexes_of_new_positions) - + #remove the active piece with old position @chessboard.remove(@chessboard.active_piece) # Add the active piece with the new position @@ -132,28 +183,32 @@ def human_vs_human end break if do_break - current_player == player_1 ? current_player = player_2 : current_player = player_1 + current_player == @player_human_1 ? current_player = @player_human_2 : current_player = @player_human_1 end end def human_vs_ai - puts "Player-1 What is your name?" - name1 = gets.chomp - player_1 = Player.new(name1, "white") - - player_2 = AI.new("Alexa", "black") - - puts "Okay, #{player_1.name}, the white pieces have been assigned to you" - - - puts "You'll be playing with a AI called 'Alexa', the black pieces have been assigned to her" - puts "Good luck!!" + if @player_human_3.nil? + puts "Player-1 What is your name?" + name1 = gets.chomp + @player_human_3 = Player.new(name1, "white") + + @player_ai_3 = AI.new("Alexa", "black") - setup(@chessboard) + + puts "Okay, #{@player_human_3.name}, the white pieces have been assigned to you" + + sleep(3) + puts "You'll be playing with a AI called 'Alexa', the black pieces have been assigned to her" + puts "Good luck!!" + sleep(6) + + setup(@chessboard) + end - - current_player = player_1 + + current_player = @player_human_3 do_break = false loop do @chessboard.display @@ -161,19 +216,36 @@ def human_vs_ai puts "It's #{current_player.name}'s turn" puts "Choose the piece you want to move. eg(d1)" if current_player.class.name == "Player" - position_of_the_choosed_piece = gets.chomp + answer_1 = gets.chomp else - position_of_the_choosed_piece = current_player.choose_a_piece_to_move(@chessboard) + sleep(2) + answer_1 = current_player.choose_a_piece_to_move(@chessboard) end + + if answer_1 == "s" + puts "What is the name to save your progress on?" + name = gets.chomp + file = open("chessgame_data/#{name}.txt", 'w') + file.write Marshal.dump(self) + file.close + puts "Your progress has been saved!".light_green + return + elsif answer_1 == "q" + puts "Are you sure that you want to qui?[y/n]" + confirmation = gets.chomp + if confirmation == "y" + puts "You quit the game".light_red + return + end - if position_of_the_choosed_piece.length != 2 + elsif answer_1.length != 2 puts "Invalid input".light_red puts "Your position should be two characters length".light_blue sleep(3) redo - elsif (("a".."h").to_a.include?(position_of_the_choosed_piece[0]) && ("1".."8").to_a.include?(position_of_the_choosed_piece[1])) - array_index_positions = convert(position_of_the_choosed_piece) + elsif (("a".."h").to_a.include?(answer_1[0]) && ("1".."8").to_a.include?(answer_1[1])) + array_index_positions = convert(answer_1) @chessboard.active_piece = @chessboard.data[array_index_positions[0]][array_index_positions[1]] @@ -191,7 +263,7 @@ def human_vs_ai puts "Please choose another one".light_blue sleep(3) redo - + else @chessboard.display current_player.show_captured_piece @@ -200,19 +272,35 @@ def human_vs_ai if current_player.class.name == "Player" new_position = gets.chomp else + sleep(3) new_position = current_player.choose_a_position_to_move(@chessboard.active_piece) end - if new_position.length != 2 + if new_position == "s" + puts "What is the name to save your progress on?" + name = gets.chomp + file = open("chessgame_data/#{name}.txt", 'w') + file.write Marshal.dump(self) + file.close + puts "Your progress has been saved!".light_green + return + elsif new_position == "q" + puts "Are you sure that you want to qui?[y/n]" + confirmation = gets.chomp + if confirmation == "y" + puts "You quit the game".light_red + return + end + elsif new_position.length != 2 puts "Invalid input".light_red puts "Your position should be two characters length".light_blue redo elsif (("a".."h").to_a.include?(new_position[0]) && ("1".."8").to_a.include?(new_position[1])) array_indexes_of_new_positions = convert(new_position) - + # Check if the position of the choosed piece is included inside the active_piece's attack_moves if @chessboard.active_piece.attack_moves.include?(array_indexes_of_new_positions) the_attacked_piece = @chessboard.data.dig(array_indexes_of_new_positions[0], array_indexes_of_new_positions[1]) - + if the_attacked_piece.class.name == "King" do_break = true puts "CHECKMATE".light_green @@ -220,25 +308,25 @@ def human_vs_ai break end - + # Capture the enemy's piece @chessboard.remove(the_attacked_piece) the_attacked_piece.position = nil current_player.captured_pieces << the_attacked_piece - + #remove the active piece with old position @chessboard.remove(@chessboard.active_piece) - + # Add the active piece to the new position @chessboard.active_piece.position = array_indexes_of_new_positions @chessboard.add(@chessboard.active_piece) @chessboard.active_piece = nil break - + # Check if the position of the choosed piece is included inside the active_piece's allowed_moves elsif @chessboard.active_piece.allowed_moves.include?(array_indexes_of_new_positions) - + #remove the active piece with old position @chessboard.remove(@chessboard.active_piece) # Add the active piece with the new position @@ -266,34 +354,38 @@ def human_vs_ai end break if do_break - current_player == player_1 ? current_player = player_2 : current_player = player_1 + current_player == @player_human_3 ? current_player = @player_ai_3 : current_player = @player_human_3 end end def ai_vs_ai - player_1 = AI.new("Siri", "white") - - player_2 = AI.new("Alexa", "black") - - puts "Hello, my name is #{player_1.name}, and i'll play with the white pieces" - sleep(3) - puts "Hello, my name is #{player_2.name}, and i'll play with the black pieces" - sleep(3) - setup(@chessboard) + if @player_ai_1.nil? + @player_ai_1 = AI.new("Siri", "white") + puts "Hello, my name is #{@player_ai_1.name}, and i'll play with the white pieces" + sleep(3) + end + if @player_ai_2.nil? + @player_ai_2 = AI.new("Alexa", "black") - puts "Let's start playing chess right now".light_blue - current_player = player_1 + + puts "Hello, my name is #{@player_ai_2.name}, and i'll play with the black pieces" + sleep(3) + setup(@chessboard) + puts "Let's start playing chess right now".light_blue + end + + current_player = @player_ai_1 do_break = false loop do @chessboard.display current_player.show_captured_piece puts "It's #{current_player.name}'s turn" sleep(1) - position_of_the_choosed_piece = current_player.choose_a_piece_to_move(@chessboard) - - array_index_positions = convert(position_of_the_choosed_piece) + answer_1 = current_player.choose_a_piece_to_move(@chessboard) + + array_index_positions = convert(answer_1) @chessboard.active_piece = @chessboard.data[array_index_positions[0]][array_index_positions[1]] @@ -307,33 +399,33 @@ def ai_vs_ai if @chessboard.active_piece.attack_moves.include?(array_indexes_of_new_positions) the_attacked_piece = @chessboard.data.dig(array_indexes_of_new_positions[0], array_indexes_of_new_positions[1]) - + if the_attacked_piece.class.name == "King" do_break = true puts "CHECKMATE".light_green puts "Congratulations #{current_player.name}, you win!!!".light_green break end - - + + # Capture the enemy's piece @chessboard.remove(the_attacked_piece) the_attacked_piece.position = nil current_player.captured_pieces << the_attacked_piece - + #remove the active piece with old position @chessboard.remove(@chessboard.active_piece) - + # Add the active piece to the new position @chessboard.active_piece.position = array_indexes_of_new_positions @chessboard.add(@chessboard.active_piece) @chessboard.active_piece = nil break - + # Check if the position of the choosed piece is included inside the active_piece's allowed_moves elsif @chessboard.active_piece.allowed_moves.include?(array_indexes_of_new_positions) - + #remove the active piece with old position @chessboard.remove(@chessboard.active_piece) # Add the active piece with the new position @@ -347,7 +439,7 @@ def ai_vs_ai end end break if do_break - current_player == player_1 ? current_player = player_2 : current_player = player_1 + current_player == @player_ai_1 ? current_player = @player_ai_2 : current_player = @player_ai_1 end end @@ -380,3 +472,6 @@ def convert(input) end end + +data = "chessgame_data" +Dir.mkdir(data) unless File.exist? data diff --git a/main.rb b/main.rb index df1fbba..ed3fbfa 100644 --- a/main.rb +++ b/main.rb @@ -1,30 +1,34 @@ -require_relative 'lib/game.rb' +require_relative 'lib/game' +require_relative 'serializable' + loop do - puts "Please choose from the following: 1) Human vs Human - 2) Human vs AI - 3) AI vs AI - 4) Load an old game - 5) View a game from the collection library - " + puts "Please choose from the following: + 1) Human vs Human + 2) Human vs AI + 3) AI vs AI + 4) Load an old game + 5) View names from the collection library" answer = gets.chomp game = ChessGame.new if answer == "1" - game.human_vs_human - + game.play(answer) elsif answer == "2" - game.human_vs_ai + game.play(answer) elsif answer == "3" - game.ai_vs_ai + game.play(answer) elsif answer == "4" - - elsif answer == "5" - + choose_name + elsif "5" + show_saved_names + choose_name else puts "This option doesn't exist" redo end + puts "Do you want to play again[y/n]" play_again = gets.chomp + if play_again == "y" redo else @@ -33,5 +37,3 @@ break end end - - \ No newline at end of file diff --git a/serializable.rb b/serializable.rb new file mode 100644 index 0000000..88eab33 --- /dev/null +++ b/serializable.rb @@ -0,0 +1,25 @@ +def show_saved_names + data_directory = Dir.glob("chessgame_data/*.txt") + data_directory.each { |path| puts File.basename(path).chomp(".txt") } +end + +def choose_name + puts "What is the name you saved?" + name = gets.chomp + + if File.exist? "chessgame_data/#{name}.txt" + puts "We found your progress, You can continue where you left off".light_green + file = open("chessgame_data/#{name}.txt", 'r') + loaded_game = Marshal.load(file.read) + option = loaded_game.option + if option == "1" + loaded_game.human_vs_human + elsif option == "2" + loaded_game.human_vs_ai + else + loaded_game.ai_vs_ai + end + else + puts "This name doesn't exist in our database".light_red + end +end \ No newline at end of file