Description:
The game “Captain’s Mistress”, also known as “Connect Four”.
https://en.wikipedia.org/wiki/Connect_Four
Standard Connect Four configuration and rules apply:
* There are two players.
* The board should be seven columns wide.
* The board should be six rows high.
* It takes four pieces in a row to win.
Your implementation of the game should meet the following criteria:
* Players place their discs by entering a column number on the command line.
* The board should be rendered after each turn.
* If a winning move is played, the winning board should be rendered and the
winner should be displayed.
Ruby implementation:
require 'captains_mistress/version' # A simple game of Captain's Mistress. module CaptainsMistress class Player @disc @steps @win def initialize(name) @name = name @steps = Array.new() @win = false end attr_reader :name attr_reader :disc attr_reader :steps attr_reader :win def setDisc(number) @disc = number end def setWin(win) @win = win end end class Engine @board = Array.new(6){Array.new(7,0)} @player1 @player2 @winner @gameOver @validColumnNumber def initialize(board, player1, player2) @board = board @player1 = player1 @player2 = player2 @validColumnNumber = ["0", "1", "2", "3", "4", "5", "6"] initialPlayerDiscs() decideFirst() renderBoard() end attr_reader :board attr_reader :player1 attr_reader :player2 attr_reader :winner attr_reader :gameOver attr_reader :validColumnNumber def initialPlayerDiscs() random = rand(1..100) if(random%2 == 0) @player1.setDisc(1) @player2.setDisc(2) else @player1.setDisc(2) @player2.setDisc(1) end getPlayerDisc() end #decide who goes first def decideFirst() random = rand(1..100) if(random%2 == 0) firstHand = @player1 else firstHand = @player2 end puts "#{firstHand::name} goes first" puts "" end def addDisc(player, columnIndex) puts "columnIndex = #{columnIndex}" if(!@validColumnNumber.include?(columnIndex)) warnningOfInvalid(player) return false; else columnIndex = columnIndex.to_i end rowIndex = updateBoard(player, columnIndex) if(columnIndex >= @board[0].length || columnIndex <0) warnningOfInvalid(player) return false elsif(rowIndex == -1) warnningOfInvalid(player) return false elsif(checkWin(player, columnIndex, rowIndex)) setWinner(player) @gameOver = true else end updatePlayerStatus(player, columnIndex) if(@gameOver) renderFinalResult() exit(1) else renderBoard() end puts "addDisc successfully" puts "" return true end def updateBoard(player, columnIndex) rowIndex = @board.length if(@board[0][columnIndex] != 0) warnningOfInvalid(player) return -1 else @board.each_index do |i| if @board[@board.length-i-1][columnIndex] == 0 @board[@board.length-i-1][columnIndex] = player.disc rowIndex = @board.length-i-1 break else end end end return rowIndex end def warnningOfInvalid(player) puts "Hey #{player::name}, your input is invalid" end def updatePlayerStatus(player, columnIndex) player::steps.push(columnIndex) if(@winner == player) player.setWin(true) else end end def setWinner(player) @winner = player; end def checkWin(player, columnIndex, rowIndex) if(checkColumn(player, columnIndex, rowIndex) || checkRow(player, columnIndex, rowIndex) || checkLeftDiagonal(player, columnIndex, rowIndex) || checkRightDiagonal(player, columnIndex, rowIndex)) return true else end return false; end def checkColumn(player, columnIndex, rowIndex) disc = player::disc i = rowIndex-1 count = 1 while(i >= 0 && @board[i][columnIndex] == disc) i -= 1 count +=1 if(count == 4) return true else end end i = rowIndex+1 while(i < @board.length && @board[i][columnIndex] == disc) i += 1 count += 1 if(count == 4) return true else end end return false end def checkRow(player, columnIndex, rowIndex) disc = player::disc i = columnIndex-1 count = 1; while(i >= 0 && @board[rowIndex][i] == disc) i -=1 count +=1 if(count == 4) return true else end end i = columnIndex+1 while(i < @board[rowIndex].length && @board[rowIndex][i] == disc) i += 1 count += 1 if(count == 4) return true else end end return false end def checkLeftDiagonal(player, columnIndex, rowIndex) disc = player::disc i = rowIndex-1 j = columnIndex-1 count = 1 while(i >= 0 && j >= 0 && @board[i][j] == disc) i -=1 j -= 1 count +=1 if(count == 4) return true else end end i = rowIndex+1 j = columnIndex+1 while(i < @board.length && j < @board[0].length && @board[i][j] == disc) i += 1 j +=1 count += 1 if(count == 4) return true else end end return false; end def checkRightDiagonal(player, columnIndex, rowIndex) disc = player::disc i = rowIndex-1 j = columnIndex+1 count = 1 while(i >= 0 && j < @board.length && @board[i][j] == disc) i -=1 j +=1 count +=1 if(count == 4) return true else end end i = rowIndex=1 j = columnIndex-1 while(i < @board.length && j >= 0 && @board[i][j] == disc) i += 1 j -=1 count += 1 if(count == 4) return true else end end return false end def renderBoard() #index for each column puts "0 1 2 3 4 5 6" puts "V V V V V V V " @board.each do |r| puts r.each { |p| p }.join(" ") end puts "" end def renderFinalResult() puts "" puts "Game Over!!!!" renderBoard() puts "The winner is: #{@winner::name}. Congratulations!!!!!" puts "" end def getPlayerDisc() puts "#{@player1::name}'s disc is #{@player1::disc}" puts "#{@player2::name}'s disc is #{@player2::disc}" end def gameOver() return @gameOver end def getWinner() return @winner end end end
require 'captains_mistress' module CaptainsMistress # The application object. Create it with options for the game, then run by # calling #run. class App attr_reader :verbose def initialize(options = {}) @verbose = options.fetch(:verbose, false) end def run puts "Game of 'Captain's Mistress' " puts "" puts "Player1, please enter your name: " p1Name = $stdin.gets.chomp puts "" player1 = Player.new(p1Name) puts "Player2, please enter your name: " p2Name = $stdin.gets.chomp player2 = Player.new(p2Name) puts "" board= Array.new(6){Array.new(7,0)} game1 = Engine.new(board, player1, player2) if(game1.decideFirst() == player2.name) firstHand = plasyer2; secondHand = player1; else firstHand = player1; secondHand = player2; end round = 0 while(!game1.gameOver()) round += 1 puts "Round #{round}" firstColumnIndex = -1 begin puts "#{firstHand::name}, enter your next step: (select a column number from 0 to 6)" firstColumnIndex = $stdin.gets.chomp end while (!game1.gameOver() && !game1.addDisc(firstHand, firstColumnIndex)) if(game1.gameOver()) break else end secondColumnIndex = -1 begin puts "#{secondHand::name}, enter your next step: (select a column number from 0 to 6)" secondColumnIndex = $stdin.gets.chomp end while (!game1.gameOver() && !game1.addDisc(secondHand, secondColumnIndex)) puts "" end end end end
Java implementation:
import java.util.List; /*A class that represents a player. *Include's an integer 0 or 1 to present a player's disc type; *A boolean to indicate a player is win or not; *A list of integers to presents each step a player goes in a game. The integers are the column indexes.*/ public class Player { String name; int disc; boolean win; List<Integer> steps; public Player(String name) { this.name = name; } } import java.util.ArrayList; import java.util.Random; public class Game_Implementation { private int[][] board; private Player player1, player2, winner; private boolean gameOver; // initialization and validation of the game public Game_Implementation(int[][] board, Player player1, Player player2) { if(board == null || board.length != 6 || board[0].length != 7) { System.out.println("This is not a valid baord. The game board should have 6 rows and 7 columns"); }else{ this.board = board; this.player1 = player1; this.player2 = player2; initialPlayer(); } } private void initialPlayer() { player1.steps = new ArrayList<>(); player2.steps = new ArrayList<>(); initialPlayerDiscs(); } private void initialPlayerDiscs(){ int random = (int) Math.ceil(Math.random() * 100) ; if(random%2 == 0) { player1.disc = 1; player2.disc = 2; }else { player1.disc = 2; player2.disc = 1; } System.out.println(player1.name +"'disc is "+player1.disc); System.out.println(player2.name +"'disc is "+player2.disc); } // decide who plays first. public String decideFirst() { Random firstLot = new Random(); int random = firstLot.nextInt(100); if(random%2 == 1) return player1.name; return player2.name; } public boolean addDisc(Player player, int columnIndex) { if(columnIndex >= board[0].length || columnIndex <0) { warnningOfInvalid(player); return false; } int rowIndex = updateBoard(player, columnIndex); if(rowIndex == -1) return false; if(checkWin(player, columnIndex, rowIndex)){ setWinner(player); gameOver = true; } updatePlayerStatus(player, columnIndex); if(gameOver) { renderFinalResult(); }else{ renderBoard(); } return true; } private int updateBoard(Player player, int columnIndex) { int rowIndex = board.length; if(board[0][columnIndex] != 0) { warnningOfInvalid(player); return -1; }else{ for(int i = board.length-1; i >= 0; i--) { if(board[i][columnIndex] == 0){ board[i][columnIndex] = player.disc; rowIndex = i; break; } } } return rowIndex; } private void warnningOfInvalid (Player player) { System.out.println("Hey "+ player.name+", your movement is invalid"); } private void updatePlayerStatus(Player player, int columnIndex) { player.steps.add(columnIndex); if(winner == player) player.win = true; } private void setWinner(Player player) { winner = player; } private boolean checkWin(Player player, int columnIndex, int rowIndex) { if(checkColumn(player, columnIndex, rowIndex) || checkRow(player, columnIndex, rowIndex) || checkLeftDiagonal(player, columnIndex, rowIndex) || checkRightDiagonal(player, columnIndex, rowIndex)) return true; return false; } private boolean checkColumn(Player player, int columnIndex, int rowIndex) { int disc = player.disc; int i = rowIndex; int count = 1; while(--i >= 0 && board[i][columnIndex] == disc) { ++count; if(count == 4) return true; } i = rowIndex; while(++i < board.length && board[i][columnIndex] == disc) { ++count; if(count == 4) return true; } return false; } private boolean checkRow(Player player, int columnIndex, int rowIndex) { int disc = player.disc; int i = columnIndex; int count = 1; while(--i >= 0 && board[rowIndex][i] == disc) { ++count; if(count == 4) return true; } i = columnIndex; while(++i < board[rowIndex].length && board[rowIndex][i] == disc) { ++count; if(count == 4) return true; } return false; } private boolean checkLeftDiagonal(Player player, int columnIndex, int rowIndex) { int disc = player.disc; int i = rowIndex, j = columnIndex; int count = 1; while(--i >= 0 && --j >= 0 && board[i][j] == disc) { ++count; if(count == 4) return true; } i = rowIndex; j = columnIndex; while(++i < board.length && ++j < board[0].length && board[i][j] == disc) { ++count; if(count == 4) return true; } return false; } private boolean checkRightDiagonal(Player player, int columnIndex, int rowIndex) { int disc = player.disc; int i = rowIndex, j = columnIndex; int count = 1; while(--i >= 0 && ++j < board.length && board[i][j] == disc) { ++count; if(count == 4) return true; } i = rowIndex; j = columnIndex; while(++i < board.length && --j >= 0 && board[i][j] == disc) { ++count; if(count == 4) return true; } return false; } public void renderBoard(){ for( int i = 0; i < board.length; i++) { for(int j = 0; j < board[0].length; j++) { System.out.print(board[i][j]+ " "); } System.out.println(); } System.out.println(); } public void renderFinalResult() { System.out.println("Game Over"); renderBoard(); System.out.println("The winner is: "+ winner.name); } public void getPlayerDisc() { System.out.println(player1.name +"'s disc is "+ player1.disc); System.out.println(player2.name +"'s disc is "+ player2.disc); } public boolean gameOver(){ return gameOver; } public Player getWinner(){ return winner; } } import java.util.Scanner; public class PlayTheGame { public static void main(String args[]) { System.out.println("Game of 'Captain's Mistress' "); @SuppressWarnings("resource") Scanner scanner = new Scanner(System.in); int[][] board = new int[6][7]; System.out.println("Player1, please enter your name: "); String p1Name = scanner.nextLine(); Player player1 = new Player(p1Name); System.out.println("Player2, please enter your name: "); String p2Name = scanner.nextLine(); Player player2 = new Player(p2Name); System.out.println(); Game_Implementation game1 = new Game_Implementation(board,player1, player2); System.out.println(); Player firstHand = player1; Player secondHand = player2; if(game1.decideFirst() == player2.name) { firstHand = player2; secondHand = player1; } System.out.println(); System.out.println(firstHand.name + " gose first"); System.out.println(); int round = 0; while(!game1.gameOver()) { System.out.println("TestRound = "+(round++)); int firstColumnIndex; do{ System.out.println( firstHand.name + ", enter your next step: "); firstColumnIndex = scanner.nextInt(); System.out.println(); } while(!game1.gameOver() && !game1.addDisc(firstHand, firstColumnIndex)); if(game1.gameOver()) break; int secondColumnIndex; do{ System.out.println(secondHand.name + ", enter your next step: "); secondColumnIndex = scanner.nextInt(); System.out.println(); } while(!game1.gameOver() && !game1.addDisc(secondHand, secondColumnIndex)); } System.out.println("Congratulations to "+ game1.getWinner().name); } }