Connect 4 with MVC

In this section, we will use the Model-View-Controller architecture to implement a Connect Four game. Again, we will first divide this game into model, view, and controller components, and then implement each piece:

IO (View component)

  • Scanner field/constructor to initialize
  • public void printBoard(String board)
  • public int getMove(char piece)
  • public void printResults(String msg)

Board (Model component)

  • char[][] field/constructor to initialize
  • public boolean move(int column, char piece)
  • public boolean full()
  • public String toString()
  • public boolean winner(char piece)

ConnectFour (Controller component)

  • Single main method – call back and forth between IO and Board

Connect 4 implementation

Here’s the implementation of each class:

import java.util.*;

public class IO 
{
    private Scanner s;

    public IO() 
    {
        s = new Scanner(System.in);
    }

    public void printBoard(String board) 
    {
        System.out.println("\nCurrent board:\n");
        System.out.println(board);
        System.out.println();
    }

    public int getMove(char piece) 
    {
        System.out.printf("User %c, enter a column: ", piece);
        return s.nextInt();
    }

    public void printResults(String msg) 
    {
     System.out.printf("%s%n%n", msg;
    }
}

public class Board 
{
    private char[][] board;

    public Board() 
    {
        board = new char[6][7];
        
        for (int i = 0; i < 6; i++) 
        {
            for (int j = 0; j < 7; j++) 
            {
                board[i][j] = '_';
            }
        }
    }

    public boolean move(int column, char piece) 
    {
        if (column < 0 || column > 6) 
        {
            return false;
        }
        else if (board[0][column] != '_') 
        {
            return false;
        }
        else 
        {
            int i;
            for (i = 5; i>=0 && board[i][column] != '_'; i--) 
            {
                board[i][column] = piece;
            }
        }
    }

    public boolean full() 
    {
        for (int i = 0; i < 6; i++) 
        {
            for (int j = 0; j < 7; j++) 
            {
                if (board[i][j] == '_') return false;
            }
        }

        return true;
    }

    //NOTE: a StringBuilder would be much more efficient
    public String toString() 
    {
        String result = "";
        for (int i = 0; i < 6; i++) 
        {
            for (int j = 0; j < 7; j++) 
            {
                result += board[i][j] + " ";
            }

            result += "\n";
        }

        return result;
    }

    public boolean winner(char piece) 
    {
        //check row win
        for (int i = 0; i < 6; i++) 
        {
            for (int j = 0; j < 3; j++) 
            {
                int x;
                for(x = 0; x < 4; x++) 
                {
                    if (board[i][j+x] != piece) break;
                }

                if (x == 4) return true;
            }
        }

        //check column win
        for (int j = 0; j < 7; j++) 
        {
            for (int i = 0; i < 2; i++) 
            {
                int x;
                for (x = 0; x < 4; x++) 
                {
                    if (board[i+x][j] != piece) break;
                }

                if (x == 4) return true;
            }
        }

        //check / diagonals
        for (int i = 0; i < 3; i++) 
        {
            for (int j = 0; j < 4; j++) 
            {
                int x;
                for (x = 0; x < 4; x++) 
                {
                    if (board[i+x][j+3-x] != piece) break;
                }

                if (x == 4) return true;
            }
        }

        //check \ diagonals
        for (int i = 0; i < 3; i++) 
        {
            for (int j = 0; j < 4; j++) 
            {
                int x;
                for (x = 0; x < 4; x++) 
                {
                    if (board[i+x][j+x] != piece) break;
                }

                if (x == 4) return true;
            }
        }

        return false;
    }
}

public class ConnectFour 
{
    public static void main(String[] args) 
    {
        IO io = new IO();
        Board b = new Board();

        char piece = 'X';
        io.printBoard(b.toString());

        while (b.full() == false) 
        {
            int col = io.getMove(piece);
            boolean worked = b.move(col, piece);
            if (worked) 
            {
                io.printBoard(b.toString());

                if (b.winner(piece) == true) 
                {
                    io.printResults(piece + " wins!");

                    //this will leave the program
                    return;
                }

                //switch the turn
                if (piece == 'X') piece = 'O';
                else piece = 'X';
            }
            else 
            {
                io.printResults("Invalid move");
            }
        }

        //we would have quit the program if someone had won
        io.printResults("Tie game");
    }
}