Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ильиных Анна #16

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
99 changes: 98 additions & 1 deletion index.html
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,112 @@

<!-- подключаем стили, чтобы тесты вяглядели красиво -->
<link href="node_modules/mocha/mocha.css" rel="stylesheet"/>
<style>
table {
border-collapse: collapse;

border-style: hidden;
}

td {
width: 100px;
height: 100px;

cursor: pointer;
transition: background-color .2s ease-out;

border: 2px solid black;
background-color: #91e6f3;
}

td:hover {
background-color: cyan;
}

.val {
position: relative;
}

.val:before {
font-size: 80px;

position: absolute;
top: 8px;
left: 22px;

display: none;

content: '\2718';
pointer-events: none;

opacity: 0;
}

.val:after {
font-size: 100px;
font-weight: bold;

position: absolute;
top: -11px;
left: 18px;

display: none;

content: '\26AC';
pointer-events: none;

opacity: 0;
}

.current_x td:hover input:not([value]) + .val:before,
.current_o td:hover input:not([value]) + .val:after {
display: inline-block;

opacity: .2;
}

input[value='x'] + .val:before {
display: inline-block;

opacity: 1;
}

input[value='o'] + .val:after {
display: inline-block;

opacity: 1;
}

</style>
</head>
<body>
<!-- относительно этого элемента выводится тестовый отчет -->
<div id="mocha"></div>

<table id="playing-field" class="current_x">
<tr>
<td><input type="text" hidden id="0-0"><span class="val"></span></td>
<td><input type="text" hidden id="0-1"><span class="val"></span></td>
<td><input type="text" hidden id="0-2"><span class="val"></span></td>
</tr>
<tr>
<td><input type="text" hidden id="1-0"><span class="val"></span></td>
<td><input type="text" hidden id="1-1"><span class="val"></span></td>
<td><input type="text" hidden id="1-2"><span class="val"></span></td>
</tr>
<tr>
<td><input type="text" hidden id="2-0"><span class="val"></span></td>
<td><input type="text" hidden id="2-1"><span class="val"></span></td>
<td><input type="text" hidden id="2-2"><span class="val"></span></td>
</tr>
</table>
<button id="startGameButton" onclick="startNewGame()">New game</button>
<div id="winmsg"></div>

<!-- подключаем файл с логикой определения победителя -->
<script src="index.js"></script>

<!-- подключаем файл с библиотекой ассертов -->
<!--подключаем файл с библиотекой ассертов-->
<script src="node_modules/chai/chai.js"></script>

<!-- конфигурируем и запускаем тесты -->
Expand Down
86 changes: 85 additions & 1 deletion index.js
Original file line number Diff line number Diff line change
@@ -1 +1,85 @@
// Реализуй логику выбора победителя в этом файле
const playingField = document.getElementById('playing-field');
let currentPlayer = 'x';
let canChangePlayer = true;
/* Инпуты игрового поля */
let playingFieldInputs = new Array(9);
for (var x = 0; x < 3; x++) {
for (var y = 0; y < 3; y++) {
playingFieldInputs[x * 3 + y] = document.getElementById(x + "-" + y)
}
}

function getCellValue(row, column) {
const input = document.getElementById(row + '-' + column);
return input.value;
}

/* Очищаем игровое поле, устанавливаем текущего игрока и очищаем запись о победители*/
function startNewGame(fieldInputs) {
playingFieldInputs.forEach(input => {
input.removeAttribute('value');
});

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

playingFieldInputs.forEach(input => input.removeAttribute('value'));

currentPlayer = 'x'
playingField.setAttribute('class', 'current_' + currentPlayer);
document.getElementById("winmsg").innerText = ""
canChangePlayer = true
}

// Логика определения победителя!!
/* Возвращает символ победителя либо пустую строку либо ничью */
function getWinMsg() {
let winMsg = undefined;

/* Возвращает элемент, содержащийся во всех ячейках, иначе пустую строку*/
function getSomeValue(valuesToCheck) {
const checkedValue = valuesToCheck[0];
if (valuesToCheck.every(valueToCheck => valueToCheck == checkedValue)){
return checkedValue;
}
else{
return "";
}
}
// Текущие состояние доски
const gameValues = playingFieldInputs.map(inp => inp.value);
// проверка горизонтальных линий
winMsg = getSomeValue(gameValues.slice(0, 3)) + getSomeValue(gameValues.slice(3, 6)) + getSomeValue(gameValues.slice(6, 9))
// проверка вертикальных линий
+ getSomeValue([gameValues[0], gameValues[3], gameValues[6]])
+ getSomeValue([gameValues[1], gameValues[4], gameValues[7]])
+ getSomeValue([gameValues[2], gameValues[5], gameValues[8]])
// проверка диагоналей
+ getSomeValue([gameValues[0], gameValues[4], gameValues[8]])
+ getSomeValue([gameValues[2], gameValues[4], gameValues[6]])

// если победитель не определён и все ячейки заполнены
if (winMsg.length == 0 && !gameValues.some(value => value == "")){
winMsg = "ничья"
}
return winMsg;
}

playingField.addEventListener('click', event => {
if(!canChangePlayer){
return;
}
canChangePlayer = false;

const cell = event.target;
const hiddenInput = cell.getElementsByTagName('input')[0];
if (!hiddenInput.value) {
hiddenInput.setAttribute('value', currentPlayer);
currentPlayer = currentPlayer === 'x' ? 'o' : 'x';
playingField.setAttribute('class', 'current_' + currentPlayer);
}

canChangePlayer = true;

const winMsg = getWinMsg()
if (winMsg.length > 0) {
const winMsgDiv = document.getElementById("winmsg")
winMsgDiv.innerText = winMsg
canChangePlayer = false
}
})
;
80 changes: 78 additions & 2 deletions tests/index-test.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,80 @@
describe('cross-zero', () => {
// Этот тест можно уалить, он нужен для проверки сборки
it('should sum digits', () => chai.assert(1 + 1, 2));

function clickCell(id) {
document.getElementById(id).parentNode.click();
}
function getWinnerMsg() {
return document.getElementById("winmsg").innerText
}
function startNewGameByButtonClicking() {
return document.getElementById("startGameButton").click()
}
// две линии по горизонтале, x просто первее закончит
it('should win x - horizontal', () => {
startNewGameByButtonClicking()
clickCell("0-0");
clickCell("1-0");
clickCell("0-1");
clickCell("1-1");
clickCell("0-2");
clickCell("1-2");
chai.assert.equal(getWinnerMsg(), 'x');
});
// две линии по горизонтале, x на 2ом шаге ставит на другую линию, отдавая победу o
it('should win o horizontal', () => {
startNewGameByButtonClicking()
clickCell("0-0");
clickCell("1-0");
clickCell("2-1");
clickCell("1-1");
clickCell("0-2");
clickCell("1-2");
chai.assert.equal(getWinnerMsg(), 'o');
});

it('should win x vertical', () => {
startNewGameByButtonClicking()
clickCell("0-0");
clickCell("1-1");
clickCell("2-0");
clickCell("0-1");
clickCell("1-0");
clickCell("2-2");
chai.assert.equal(getWinnerMsg(), 'x');
});

it('should win o vertical', () => {
startNewGameByButtonClicking()
clickCell("0-0");
clickCell("1-0");
clickCell("2-1");
clickCell("1-1");
clickCell("2-2");
clickCell("1-2");
chai.assert.equal(getWinnerMsg(), 'o');
});

it('should win x diagonal', () => {
startNewGameByButtonClicking()
clickCell("0-0");
clickCell("0-1");
clickCell("1-0");
clickCell("1-1");
clickCell("2-0");
chai.assert.equal(getWinnerMsg(), 'x');
});

it('without winners', () => {
startNewGameByButtonClicking()
clickCell("0-0");
clickCell("0-1");
clickCell("0-2");
clickCell("1-1");
clickCell("1-0");
clickCell("2-0");
clickCell("2-1");
clickCell("2-2");
clickCell("1-2");
chai.assert.equal(getWinnerMsg(), 'ничья');
});
});