Captain’s Mistress- An implementation of a simple game

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);
	}

}

Leave a comment