Подключите четыре варианта, позволяя только горизонтальные и вертикальные побед


Я совершенно нового в JavaScript (и в программировании в целом). Я сделал подключить четыре игры, который проверяет победитель по вертикали и горизонтали (я еще не разобрался, как решить ее по диагонали).

Кто-нибудь может указать на ошибки, которые я сделал в эту программу, или/и как улучшить код?

HTML-код:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Fire på Stribe</title>
</head>
<center>
<br/>
<div style="font-family:Arial,sans-serif; font-size:14pt; font-weight:bold; color: black" id="p1">Velkommen til fire på stribe</div><br/>
<body bgcolor="#87cefa">
<div style="font-family:Arial,sans-serif; font-size:14pt; font-weight:bold; color: blue" id="spiller1"></div>
<div style="font-family:Arial,sans-serif; font-size:14pt; font-weight:bold; color: red" id="spiller2"></div><br/>
<button style="background-color: antiquewhite; border-radius: 16px" id = "col1" onclick = "putPieceInColumnNo(0);"> - - 1 - -</button>
<button style="background-color: antiquewhite; border-radius: 16px" id = "col2" onclick = "putPieceInColumnNo(1);"> - - 2 - -</button>
<button style="background-color: antiquewhite; border-radius: 16px" id = "col3" onclick = "putPieceInColumnNo(2);"> - - 3 - -</button>
<button style="background-color: antiquewhite; border-radius: 16px" id = "col4" onclick = "putPieceInColumnNo(3);"> - - 4 - -</button>
<button style="background-color: antiquewhite; border-radius: 16px" id = "col5" onclick = "putPieceInColumnNo(4);"> - - 5 - -</button>
<button style="background-color: antiquewhite; border-radius: 16px" id = "col6" onclick = "putPieceInColumnNo(5);"> - - 6 - -</button>
<button style="background-color: antiquewhite; border-radius: 16px" id = "col7" onclick = "putPieceInColumnNo(6);"> - - 7 - -</button><br>
<canvas id="mycanvas" width="420" height="420"></canvas>
</center>
<center><button style="border-radius:16px; background-color: antiquewhite" id="restart" onclick="reloadPage();">Genstart spillet</button></center><br/>
<script src="projektfps.js"></script>
</body>
</html>

ДШ:

let context = document.getElementById("mycanvas").getContext('2d');
context.fillStyle = "antiqueWhite";
context.fillRect(0,0,420,375);

let col = 7; 
let row = 6; 
let x = 28; 
let y = 35; 
let r = 25; 
let activePlayer =1;

let column0 = [0,0,0,0,0,0];
let column1 = [0,0,0,0,0,0];
let column2 = [0,0,0,0,0,0];
let column3 = [0,0,0,0,0,0];
let column4 = [0,0,0,0,0,0];
let column5 = [0,0,0,0,0,0];
let column6 = [0,0,0,0,0,0];
let columns = [column0,column1,column2, column3, column4, column5, column6];
console.log(columns);

//Players:
let name1 = prompt("Indtast spiller 1's navn:");
document.getElementById("spiller1").innerHTML = "Spiller 1: " + name1;

let name2 = prompt("Indtast spiller 2's navn:");
document.getElementById("spiller2").innerHTML = "Spiller 2: " + name2;

drawBoard();

//-------Functions--------

function drawBoard() {
    for(let i = 0; i < col ; i++){
        for (let j = 0 ; j < row ; j++){
            drawCircle(x + i *60, y + j*60, r);
            context.strokeStyle = "black";
            context.stroke();
            context.fillStyle = "white";
            context.fill();
        }
    }
}

function putPieceInColumnNo(no){
    let activeColumn = columns[no];
    let height = 0;

    for (let i = 0 ; i < activeColumn.length ; i++){
        if (activeColumn[i] === 0){
            activeColumn[i] = activePlayer;
            drawPieceAt(no,5-i,activePlayer);
            height = i;
            i = activeColumn.length
        }
    }
    let winner = checkWinnerVertical(activePlayer,no);
    if (winner===true){
        publishWinner();
    }
    winner = checkWinnerHorizontal(activePlayer,height);
    if (winner===true){
        publishWinner();
    }
    swapPl();
}

function checkWinnerVertical(activePlayer, no){
    let activeCol = columns[no];
    let inARow = 0;
    for(let i=0;i<activeCol.length;i++){
        if(activeCol[i]===activePlayer){
            inARow++;
        } else {
            inARow=0;
        }
        if(inARow>=4){
            return true;
        }
    }
    return false;
}

function checkWinnerHorizontal(activePlayer, height) {
    let inACol = 0;
    for (let i = 0; i < columns.length ; i++){
        if (columns[i][height] === activePlayer){
            inACol++;
        } else {
            inACol = 0;
        }
        if (inACol >= 4){
            return true;
        }
    }
    return false;
}

function swapPl() {
    if (activePlayer===1){
        activePlayer=2;
    } else {
        activePlayer=1;
    }
}

function reloadPage(){
    window.location.reload();
}

function drawPieceAt(x, y, activePlayer) {
    let color = 'red';
    if (activePlayer === 1){
        color = 'blue'
    }
    drawCircle(28+x*60, 35+y*60, r, color);
}

function drawCircle(x, y, r, fill) {
    //Fill the circle if fill is set
    if (fill){
        //debugger;
        context.beginPath();
        context.arc(x, y, r, 0, Math.PI*2);
        context.fillStyle = fill;
        context.fill();
    } else {
        context.beginPath();
        context.arc(x, y, r, 0, Math.PI*2);
        context.stroke();
    }
}

function publishWinner(){
    if (activePlayer ===1){
        alert("Tillykke " + name1 +" du har vundet!!");
    }else{
        alert("Tillykke " + name2 +" du har vundet!!")
    }
}


Комментарии
1 ответ

Общий дизайн

Я заметил, что если будет выдано предупреждение с сообщением, что данный выигрывает пользователя, затем кнопок столбца еще может быть нажата, что может привести к предупреждение показывать сообщение, что другой пользователь выиграл. Обычно после того, как пользователь будет объявлен победитель, игра должна быть перезапущена...

Обратная связь код

HTML-код


<center>
<br/>
<div style="font-family:Arial,sans-serif; font-size:14pt; font-weight:bold; color: black" id="p1">Velkommen til fire på stribe</div><br/>
<body bgcolor="#87cefa">

С этой разметкой, тело тег является дочерним <center> тег (который "также считаются устаревшими"1)... это оказывается недействительным. В <center> тег (а также <div> перед ней) должен быть ребенком из тела тега.

<body bgcolor="#87cefa">
<center>
<br/>
<div style="font-family:Arial,sans-serif; font-size:14pt; font-weight:bold; color: black" id="p1">Velkommen til fire på stribe</div><br/>

Ставить избыточные стили в классы и использовать CSS

Многие из днище элементы имеют избыточные style атрибутов (т. е. background-color: antiquewhite; border-radius: 16px) - многое из того, что избыточность может быть устранена с помощью CSS. Например, имя класса может быть добавлено, или даже селектор на любую кнопку, который является дочерним элементом нового контейнера, может этот стиль применяется. То же самое верно для элементов, которые имеют атрибут id содержащих слово Спиллер.

В JavaScript

Использовать const вместо let за то, что не переназначены

Переменные, такие как context, activeColumn и winner в putPieceInColumnNo(), activeCol в checkWinnerVertical()и т. д. не переназначены и, таким образом, являются хорошими кандидатами для const вместо let. В то время как свойства константы могут быть повторно назначены, сам объект/значение не может быть повторно назначены.

Упрощение drawCircle()

Код в drawCircle() - то есть


function drawCircle(x, y, r, fill) {
//Fill the circle if fill is set
if (fill){
//debugger;
context.beginPath();
context.arc(x, y, r, 0, Math.PI*2);
context.fillStyle = fill;
context.fill();
} else {
context.beginPath();
context.arc(x, y, r, 0, Math.PI*2);
context.stroke();
}
}

можно упростить несколькими способами, включая следующие, где резервные линии удаляются (соответствует Р. Д. Ю. принцип):

function drawCircle(x, y, r, fill) {
//Fill the circle if fill is set
context.beginPath();
context.arc(x, y, r, 0, Math.PI*2);
if (fill){
context.fillStyle = fill;
context.fill();
} else {
context.stroke();
}
}

Вынести логику из onclick в HTML (вызов putPieceInColumnNo()) и использовать JavaScript делегата вместо

Вместо того, чтобы смешивать вызывает JavaScript в HTML-код, добавить код JavaScript, чтобы вызвать функцию, когда это необходимо.

document.addEventListener('click', function(event) {
if(event.target.id === 'restart') {
reloadPage();
}
else if (event.target.id.substr(0, 3) === 'col') { //could also use data-attributes
const parts = event.target.id.split('col');
putPieceInColumnNo(parts[1] - 1);
}
});

Можно также использовать атрибуты данных, чтобы указать столбец, переданных функции.

Сокращение избыточности при создании столбца:

Следующий код установки:


let column0 = [0,0,0,0,0,0];
let column1 = [0,0,0,0,0,0];
let column2 = [0,0,0,0,0,0];
let column3 = [0,0,0,0,0,0];
let column4 = [0,0,0,0,0,0];
let column5 = [0,0,0,0,0,0];
let column6 = [0,0,0,0,0,0];
let columns = [column0,column1,column2, column3, column4, column5, column6];

Может быть упрощена с помощью массива.заполнить() и массив.еогеасп()

const columns = new Array(7).fill('');
columns.forEach(function(column, index) {
columns[index] = [0,0,0,0,0,0];
});

Изначально я думал .fill() может быть использована с массивом нулей, но тогда каждый вложенный массив будет иметь те же ячейки памяти.

Рерайт

Увидеть обновленный код с советы учтены ниже в сниппете



const context = document.getElementById("mycanvas").getContext('2d');
context.fillStyle = "antiqueWhite";
context.fillRect(0, 0, 420, 375);

let col = 7;
let row = 6;
let x = 28;
let y = 35;
let r = 25;
let activePlayer = 1;

const columns = new Array(7).fill('');
columns.forEach(function(column, index) {
columns[index] = [0, 0, 0, 0, 0, 0];
});

//Players:
const name1 = prompt("Indtast spiller 1's navn:");
document.getElementById("spiller1").innerHTML = "Spiller 1: " + name1;

const name2 = prompt("Indtast spiller 2's navn:");
document.getElementById("spiller2").innerHTML = "Spiller 2: " + name2;

drawBoard();

//-------Functions--------

function drawBoard() {
for (let i = 0; i < col; i++) {
for (let j = 0; j < row; j++) {
drawCircle(x + i * 60, y + j * 60, r);
context.strokeStyle = "black";
context.stroke();
context.fillStyle = "white";
context.fill();
}
}
}
document.addEventListener('click', function(event) {
if (event.target.id === 'restart') {
reloadPage();
} else if (event.target.dataset.id) {
putPieceInColumnNo(event.target.dataset.id - 1);
}
});

function putPieceInColumnNo(no) {
const activeColumn = columns[no];
let height = 0;

for (let i = 0; i < activeColumn.length; i++) {
if (activeColumn[i] === 0) {
activeColumn[i] = activePlayer;
drawPieceAt(no, 5 - i, activePlayer);
height = i;
i = activeColumn.length
}
}
let winner = checkWinnerVertical(activePlayer, no);
if (winner === true) {
publishWinner();
}
winner = checkWinnerHorizontal(activePlayer, height);
if (winner === true) {
publishWinner();
}
swapPl();
}

function checkWinnerVertical(activePlayer, no) {
const activeCol = columns[no];
let inARow = 0;
for (let i = 0; i < activeCol.length; i++) {
if (activeCol[i] === activePlayer) {
inARow++;
} else {
inARow = 0;
}
if (inARow >= 4) {
return true;
}
}
return false;
}

function checkWinnerHorizontal(activePlayer, height) {
let inACol = 0;
for (let i = 0; i < columns.length; i++) {
if (columns[i][height] === activePlayer) {
inACol++;
} else {
inACol = 0;
}
if (inACol >= 4) {
return true;
}
}
return false;
}

function swapPl() {
if (activePlayer === 1) {
activePlayer = 2;
} else {
activePlayer = 1;
}
}

function reloadPage() {
window.location.reload();
}

function drawPieceAt(x, y, activePlayer) {
let color = 'red';
if (activePlayer === 1) {
color = 'blue'
}
drawCircle(28 + x * 60, 35 + y * 60, r, color);
}

function drawCircle(x, y, r, fill) {
//Fill the circle if fill is set
context.beginPath();
context.arc(x, y, r, 0, Math.PI * 2);
if (fill) {
//debugger;
context.fillStyle = fill;
context.fill();
} else {
context.stroke();
}
}

function publishWinner() {
if (activePlayer === 1) {
alert("Tillykke " + name1 + " du har vundet!!");
} else {
alert("Tillykke " + name2 + " du har vundet!!")
}
}


button[id^='col'] {
background-color: antiquewhite;
border-radius: 16px;
}

.spiller {
font-family: Arial, sans-serif;
font-size: 14pt;
font-weight: bold;
}
#spiller1 {
color: blue;
}
#spiller2 {
color: red;
}


<center>
<br/>
<div style="font-family:Arial,sans-serif; font-size:14pt; font-weight:bold; color: black" id="p1">Velkommen til fire på stribe</div><br/>
<div class="spiller" id="spiller1"></div>
<div class="spiller" id="spiller2"></div><br/>
<button data-id="1"> - - 1 - -</button>
<button data-id="2"> - - 2 - -</button>
<button data-id="3"> - - 3 - -</button>
<button data-id="4"> - - 4 - -</button>
<button data-id="5"> - - 5 - -</button>
<button data-id="6"> - - 6 - -</button>
<button data-id="7"> - - 7 - -</button><br>
<canvas id="mycanvas" width="420" height="420"></canvas>
</center>
<center><button style="border-radius:16px; background-color: antiquewhite" id="restart">Genstart spillet</button></center><br/>



2
ответ дан 1 августа 2018 в 11:08 Источник Поделиться