Me and my friend are trying to build a Connect4 game with a twist. The twist requires us to have a 7*7 board and to be always able to check all possibilities for a win for both players after each move.
Currently, we are just filling the board with a random distribution of 0
,1
and 2
(in the final game it will be 0
for empty, 1
for player 1, 2
for player 2) and then check if there are four of the same kind (even 0
) connected, which means someone wins.
What I would like to be interested in:
Can this part of the
checkForWin
function be any cleaner?if (winRow || winColumn || winDiagonal) { if (winRow && !winColumn && !winDiagonal) { document.getElementsByClassName("statusArea")[0].innerHTML = "WIN BY ROW"; } if (!winRow && winColumn && !winDiagonal) { document.getElementsByClassName("statusArea")[0].innerHTML = "WIN BY COLUMN"; } if (!winRow && !winColumn && winDiagonal) { document.getElementsByClassName("statusArea")[0].innerHTML = "WIN BY DIAGONAL"; } if (winRow && winColumn && !winDiagonal) { document.getElementsByClassName("statusArea")[0].innerHTML = "WIN BY ROW AND COLUMN"; } if (winRow && !winColumn && winDiagonal) { document.getElementsByClassName("statusArea")[0].innerHTML = "WIN BY ROW AND DIAGONAL"; } if (!winRow && winColumn && winDiagonal) { document.getElementsByClassName("statusArea")[0].innerHTML = "WIN BY COLUMN AND DIAGONAL"; } if (winRow && winColumn && winDiagonal) { document.getElementsByClassName("statusArea")[0].innerHTML = "WIN BY ROW, COLUMN AND DIAGONAL"; } }
Some testing to check if the
checkForWin
function really always does what we want it to. I tried a lot of random distributions, but I'm just not sure if everything works out the right way.- I really had to mess around with the CSS until it looked like it does now. Please help me to clean this up.
- General comments, style advice and hints for HTML, CSS and JS.
// jshint esversion:6
// jshint browser: true
// jshint devel: true
var matrix = Array(7)
.fill(null)
.map(() => Array(7)
.fill(0));
var fieldtoken = [0, 1, 2]; // possible states a field can have. 0 for empty, 1 for player 1, 2 for player 2
var coordinates = false; // switch to true to see the coordinates in the fields
// we are currently just filling the board with a random distribution of the field tokens
function randomEntry() {
return fieldtoken[Math.floor(Math.random() * 3)];
}
function fillMatrix() {
for (var i = 6; i > -1; i--) {
for (var j = 6; j > -1; j--) {
if (coordinates) {
matrix[i][j] = "column" + i + "<br>row" + j;
} else {
matrix[i][j] = randomEntry();
}
}
}
}
fillMatrix();
//convert javascript matrix into html matrix
//note that we create columns from left to right and rows from bottom to top
function drawMatrix() {
var gameArea = document.getElementsByClassName("gameArea")[0];
for (var i = 0; i < 7; i++) {
//create columns
var column = document.createElement("div");
column.className = "column";
gameArea.appendChild(column);
for (var j = 6; j > -1; j--) {
//create fields
var field = document.createElement("div");
field.className = "field";
var textfield = document.createElement("div");
textfield.className = "textfield";
textfield.innerHTML = matrix[i][j];
column.appendChild(field);
field.appendChild(textfield);
}
}
}
drawMatrix();
var winRow = false;
var winColumn = false;
var winDiagonal = false;
function checkForWin() {
checkRows();
checkColumns();
checkDiagonals();
if (winRow || winColumn || winDiagonal) {
if (winRow && !winColumn && !winDiagonal) {
document.getElementsByClassName("statusArea")[0].innerHTML = "WIN BY ROW";
}
if (!winRow && winColumn && !winDiagonal) {
document.getElementsByClassName("statusArea")[0].innerHTML = "WIN BY COLUMN";
}
if (!winRow && !winColumn && winDiagonal) {
document.getElementsByClassName("statusArea")[0].innerHTML = "WIN BY DIAGONAL";
}
if (winRow && winColumn && !winDiagonal) {
document.getElementsByClassName("statusArea")[0].innerHTML = "WIN BY ROW AND COLUMN";
}
if (winRow && !winColumn && winDiagonal) {
document.getElementsByClassName("statusArea")[0].innerHTML = "WIN BY ROW AND DIAGONAL";
}
if (!winRow && winColumn && winDiagonal) {
document.getElementsByClassName("statusArea")[0].innerHTML = "WIN BY COLUMN AND DIAGONAL";
}
if (winRow && winColumn && winDiagonal) {
document.getElementsByClassName("statusArea")[0].innerHTML = "WIN BY ROW, COLUMN AND DIAGONAL";
}
}
}
function checkRows() {
//four in a row
for (var j = 0; j < 7; j++) {
var currentCount = 1;
var currentToken = matrix[0][j];
for (var i = 1; i < 7; i++) {
if (currentToken === matrix[i][j]) {
currentCount++;
if (currentCount === 4) {
winRow = true;
break;
}
} else {
currentToken = matrix[i][j];
currentCount = 1;
}
}
}
}
function checkColumns() {
//four in a column
for (var i = 0; i < 7; i++) {
var currentCount = 1;
var currentToken = matrix[i][0];
for (var j = 1; j < 7; j++) {
if (currentToken === matrix[i][j]) {
currentCount++;
if (currentCount === 4) {
winColumn = true;
break;
}
} else {
currentToken = matrix[i][j];
currentCount = 1;
}
}
}
}
function checkDiagonals() {
//four in a diagonal
//bottom left to top right diagonals
//idea: search from start points for these diagonals. start points are the fields in the bottom left 4*4 square
checkBLTRdiagonals();
//top left to bottom right diagonals
//idea: search from start points for these diagonals. start points are the fields in the top left 4*4 square
checkTLBRdiagonals();
}
function checkBLTRdiagonals() {
for (var j = 0; j < 4; j++) {
for (var i = 0; i < 4; i++) {
var currentCount = 1;
var currentToken = matrix[i][j];
for (var step = 1; step < 4; step++) {
if (currentToken === matrix[i + step][j + step]) {
currentCount++;
} else {
break;
}
if (currentCount === 4) {
winDiagonal = true;
}
}
}
}
}
function checkTLBRdiagonals() {
for (var j = 4; j < 7; j++) {
for (var i = 0; i < 4; i++) {
var currentCount = 1;
var currentToken = matrix[i][j];
for (var step = 1; step < 4; step++) {
if (currentToken === matrix[i + step][j - step]) {
currentCount++;
} else {
break;
}
if (currentCount === 4) {
winDiagonal = true;
}
}
}
}
}
checkForWin();
/*csslint order-alphabetical: false*/
.container {
position: absolute;
top: 50%;
left: 50%;
margin-right: -50%;
transform: translate(-50%, -50%)
}
.gameArea {
display: flex;
justify-content: center;
align-items: center;
}
.column {
float: left;
}
.field {
width: 50px;
height: 50px;
background: darkred;
padding: 5px;
margin: 1px;
}
.textfield {
color: lightyellow;
text-align: center;
display: flex;
justify-content: center;
align-items: center;
width: inherit;
height: inherit;
}
.statusArea {
text-align: center;
width: 350px;
margin: auto;
color: darkred;
font-weight: bold;
font-family: monospace;
}
html {
background: linear-gradient(135deg, #0fb8ad 0%, #1fc8db 50%, #2cb5e8 100%) no-repeat center center fixed;
background-size: cover;
}
body {
background-size: cover;
}
<body>
<div class="container">
<div class="gameArea">
</div>
<div class="statusArea">Nothing happened.
</div>
</div>