From f1c31316a12a76c9b9af4b40e605eb040d7dbd43 Mon Sep 17 00:00:00 2001 From: Maksymilian Jopek Date: Tue, 28 Feb 2023 15:44:44 +0100 Subject: v1.0.0 --- battleshipFiles/battleshipBotFunctions.js | 279 ++++++++++++++++++++++++++++++ 1 file changed, 279 insertions(+) create mode 100644 battleshipFiles/battleshipBotFunctions.js (limited to 'battleshipFiles/battleshipBotFunctions.js') diff --git a/battleshipFiles/battleshipBotFunctions.js b/battleshipFiles/battleshipBotFunctions.js new file mode 100644 index 0000000..669a881 --- /dev/null +++ b/battleshipFiles/battleshipBotFunctions.js @@ -0,0 +1,279 @@ +function populateMapRandomly(player) +{ + for(let ship of player.shipsArray) + { + let isSet = false; + while(!isSet) + { + let direction = getRandomInt(0, 2) === 0 ? "horizontally" : "vertically"; + let x, y; + // if(direction === "horizontally") + if(direction === "vertically") + { + x = getRandomInt(1, MAP_SIZE - ship + 2); + y = getRandomInt(1, MAP_SIZE + 1); + } + // else if(direction === "vertically") + else if(direction === "horizontally") + { + x = getRandomInt(1, MAP_SIZE + 1); + y = getRandomInt(1, MAP_SIZE - ship + 2); + } + if(checkPositionForShip(x, y, direction, ship, player) === true) + { + isSet = true; + putShipOnGameMap(player, x, y, direction, ship, false); + } + } + } +} + +function botShot(bot, user, ai) +{ + // console.log("Shot number: " + ai.numberOfShots++ + (ai.shipWasShot.length !== 0 ? " (ship was shot)" : " (ship wasnt shot)")); + // console.log("Start: ", ai); + + let superPositions = calculateSuperpositionsArray(bot, ai); + let userTable = document.getElementById("userTable"); + let shotIndex = {x: 'x', y: 'y'}; + + if(ai.shipWasShot.length !== 0) + { + let x = ai.shipWasShot[0]; + let y = ai.shipWasShot[1]; + + if(!ai.shotShipDirection) + { + let possibleShots = new Map(); + if(x !== 1) + possibleShots.set("up", [superPositions[x - 1][y], x - 1, y]); + if(x !== 10) + possibleShots.set("down", [superPositions[x + 1][y], x + 1, y]); + if(y !== 1) + possibleShots.set("left", [superPositions[x][y - 1], x, y - 1]); + if(y !== 10) + possibleShots.set("right", [superPositions[x][y + 1], x, y + 1]); + + possibleShots = new Map([...possibleShots.entries()].sort((a, b) => b[1][0] - a[1][0])); + + if(possibleShots.entries().next().value[0] === "up" || possibleShots.entries().next().value[0] === "down") + ai.shotShipDirection = "vertically"; + else + ai.shotShipDirection = "horizontally"; + + shotIndex.x = possibleShots.entries().next().value[1][1]; + shotIndex.y = possibleShots.entries().next().value[1][2]; + + // if(possibleShots.entries().next().value[1][0] < 1) + // ai.shipWasShot = []; + } + else + { + let beforeFirst = {x: 'x', y: 'y'}, afterLast = {x: 'x', y: 'y'}; + if(ai.shotShipDirection === "vertically") + { + // console.log("unsorted:", ai.shotShips); + ai.shotShips.sort((a, b) => a.x - b.x); + // console.log("sorted:", ai.shotShips); + beforeFirst.x = ai.shotShips.first().x - 1; + beforeFirst.y = ai.shotShips.first().y; + afterLast.x = ai.shotShips.last().x + 1; + afterLast.y = ai.shotShips.last().y; + } + else if(ai.shotShipDirection === "horizontally") + { + // console.log("unsorted:", ai.shotShips); + ai.shotShips.sort((a, b) => a.y - b.y); + // console.log("sorted:", ai.shotShips); + beforeFirst.x = ai.shotShips.first().x; + beforeFirst.y = ai.shotShips.first().y - 1; + afterLast.x = ai.shotShips.last().x; + afterLast.y = ai.shotShips.last().y + 1; + } + // if(superPositions[beforeFirst.x][beforeFirst.y] > 0 || superPositions[afterLast.x][afterLast.y] > 0) + // { + if(superPositions[beforeFirst.x][beforeFirst.y] > superPositions[afterLast.x][afterLast.y]) + { + shotIndex.x = beforeFirst.x; + shotIndex.y = beforeFirst.y; + } + else + { + + shotIndex.x = afterLast.x; + shotIndex.y = afterLast.y; + } + // } + // else + // ai.shipWasShot = []; + } + + // if(!ai.shotShips.includes({x: shotIndex.x, y: shotIndex.y})) + ai.shotShips.push({x: shotIndex.x, y: shotIndex.y}); + } + if(ai.shipWasShot.length === 0 || superPositions[shotIndex.x][shotIndex.y] === 0) + { + let indexes = getAllIndexes2D(superPositions, Math.max.apply(null, + superPositions.map(row => Math.max.apply(null, row)))); + let t = indexes[getRandomInt(0, indexes.length)]; + shotIndex.x = t[0]; + shotIndex.y = t[1]; + } + + if(user.gameMap[shotIndex.x][shotIndex.y] !== 0) + { + ai.shipWasShot = [shotIndex.x, shotIndex.y]; + user.gameMap[shotIndex.x][shotIndex.y] = 2; + ai.gameMap[shotIndex.x][shotIndex.y] = -3; + userTable.children[shotIndex.x - 1].children[shotIndex.y - 1].innerHTML = SHIP_HITTED; + + if(ai.shotShips.length === 0) + ai.shotShips.push({x: shotIndex.x, y: shotIndex.y}); + } + else + { + ai.gameMap[shotIndex.x][shotIndex.y] = -2; + userTable.children[shotIndex.x - 1].children[shotIndex.y - 1].innerHTML = SHIP_MISSED; + user.gameMap[shotIndex.x][shotIndex.y] = 3; + + if(ai.shotShips.length > 1) + ai.shotShips.pop(); + + if(ai.shotShips.length === 1) + ai.shotShipDirection = ""; + + turnChange(bot.name); + } + if(ai.shotShips.length !== 0) + checkShotShips(bot, ai, superPositions); + + // if(ai.shotShips.length !== 0) + // console.log("End: ", ai.gameMap, ai.shipWasShot, ai.shotShipDirection, ai.shotShips); + + // if([0, 3].includes(bot.gameMap[shotIndex.x][shotIndex.y]) )//user.gameMap[shotIndex.x][shotIndex.y] !== 0) + if(user.gameMap[shotIndex.x][shotIndex.y] === 2)//user.gameMap[shotIndex.x][shotIndex.y] !== 0) + { + user.destroyedShips += 1; + if(user.destroyedShips === user.howManyShips) + ifWonEndGame(user, bot); + else if(IM_SPEED || REMOVE_WAITING) + setTimeout(() => botShot(bot, user, ai), 200); + else + setTimeout(() => botShot(bot, user, ai), BOT_DELAY); + } +} + +function checkShotShips(bot, ai, superPositions) +{ + let longestShip = Math.max(...ai.shipsArray); + if(ai.shotShips.length > longestShip) + console.log("%cImpossible stanelo sie", "color: red;"); + else if(ai.shotShips.length < longestShip) + { + let xFirst = ai.shotShips.first().x, + xLast = ai.shotShips.last().x, + yFirst = ai.shotShips.first().y, + yLast = ai.shotShips.last().y; + if(ai.shotShips.length === 1) + { + for(let i = -1; i < 3; i += 2) + { + if(!checkPositionForShotShip(xFirst + i, yFirst, ai.gameMap, superPositions) + || !checkPositionForShotShip(xFirst, yFirst + i, ai.gameMap, superPositions)) + return; + } + // if(!checkPositionForShotShip(x - 1, y, ai.gameMap, superPositions) + // || !checkPositionForShotShip(x + 1, y, ai.gameMap, superPositions) + // || !checkPositionForShotShip(x, y - 1, ai.gameMap, superPositions) + // || !checkPositionForShotShip(x, y + 1, ai.gameMap, superPositions)) + // return; + } + else if(ai.shotShips.length < longestShip) + { + // console.log("%cship.length > 1", "color: lightgreen;"); + if(ai.shotShipDirection === "vertically") + { + ai.shotShips.sort((a, b) => a.x - b.x); + if(!checkPositionForShotShip(xFirst - 1, yFirst, ai.gameMap, superPositions) + || !checkPositionForShotShip(xLast + 1, yLast, ai.gameMap, superPositions)) + return; + } + else if(ai.shotShipDirection === "horizontally") + { + ai.shotShips.sort((a, b) => a.y - b.y); + if(!checkPositionForShotShip(xFirst, yFirst - 1, ai.gameMap, superPositions) + || !checkPositionForShotShip(xLast, yLast + 1, ai.gameMap, superPositions)) + return; + } + } + } + + // console.log("%cimma destroy shotShips", "color: lightblue;"); + ai.shotShips.forEach(shotShip => { + ai.gameMap[shotShip.x][shotShip.y] = -1; + }); + + removeElementFromArray(ai.shotShips.length, ai.shipsArray); + ai.shipWasShot = []; + ai.shotShips = []; + ai.shotShipDirection = ""; +} + +function checkPositionForShotShip(x, y, gameMap, superPositions) +{ + if(superPositions[x][y] === 0 || gameMap[x][y] === -2) + return true; +} + +function calculateSuperpositionsArray(bot, ai) +{ + let gameMap = createGameMap(); + + for(let ship of ai.shipsArray) + { + for(let i = 1; i <= MAP_SIZE; i++) + { + for(let j = 1; j <= MAP_SIZE; j++) + { + if(checkPositionForSuperShip(i, j, "horizontally", ship, ai)) + for(let k = j; k < j + ship; k++) + if(gameMap[i][k] !== -3) + gameMap[i][k] += 1; + if(ship !== 1 && checkPositionForSuperShip(i, j, "vertically", ship, ai)) + for(let k = i; k < i + ship; k++) + if(gameMap[k][j] !== -3) + gameMap[k][j] += 1; + } + } + } + // console.table(gameMap) + return gameMap; +} + +function checkPositionForSuperShip(x, y, direction, ship, player) +{ + if(direction === "horizontally") + { + if(y + ship <= MAP_SIZE + 1 && checkPositionForShip(x, y, "horizontally", ship, player)) + { + for(let k = y; k < y + ship; k++) + if(player.gameMap[x][k] === -2) + return false; + } + else + return false; + } + else if(direction === "vertically") + { + if(x + ship <= MAP_SIZE + 1 && checkPositionForShip(x, y, "vertically", ship, player)) + { + for(let k = x; k < x + ship; k++) + if(player.gameMap[k][y] === -2) + return false; + } + else + return false; + } + + return true; +} -- cgit v1.3.1