document.addEventListener('DOMContentLoaded', function () {
document.write(`
<!DOCTYPE HTML>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Connect 4 AI Battle</title>
<style>
body {
font-family: Arial, sans-serif;
text-align: center;
margin: 20px;
}
#game-board {
display: grid;
grid-template-columns: repeat(7, 50px);
grid-gap: 5px;
justify-content: center;
margin-top: 20px;
}
.cell {
width: 50px;
height: 50px;
border: 1px solid #000;
border-radius: 50%;
background-color: #ddd;
display: flex;
justify-content: center;
align-items: center;
}
.cell.player1 {
background-color: red;
}
.cell.player2 {
background-color: yellow;
}
#teams, #results {
margin-top: 20px;
}
.button {
margin-top: 20px;
padding: 10px 20px;
font-size: 16px;
background-color: #007BFF;
color: white;
border: none;
border-radius: 5px;
cursor: pointer;
}
.button:disabled {
background-color: #aaa;
cursor: not-allowed;
}
</style>
</head>
<body>
<h1>Connect 4 AI Battle</h1>
<div id="teams">
<p><strong>Teams:</strong></p>
<p>Red: Player 1 (Cohere AI)</p>
<p>Yellow: Player 2 (Hugging Face AI)</p>
</div>
<div id="game-board"></div>
<button id="start-button" class="button">Start Game</button>
<button id="restart-button" class="button" style="display: none;">Restart Game</button>
<div id="results"></div>
</body>
</html>
`);
const rows = 6;
const cols = 7;
let board;
let currentPlayer;
let gameActive = false;
// MH edit
const COHERE_API_KEY = "7v8CzI8JYfSUaCtS91GhhyPbAs4qOsAonlCS5JYT";
const HUGGINGFACE_API_KEY = "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";
const gameBoard = document.getElementById("game-board");
const startButton = document.getElementById("start-button");
const restartButton = document.getElementById("restart-button");
const resultsDiv = document.getElementById("results");
function initializeGame() {
board = Array.from({ length: rows }, () => Array(cols).fill(0));
gameBoard.innerHTML = "";
for (let r = 0; r < rows; r++) {
for (let c = 0; c < cols; c++) {
const cell = document.createElement("div");
cell.classList.add("cell");
cell.dataset.row = r;
cell.dataset.col = c;
gameBoard.appendChild(cell);
}
}
currentPlayer = Math.random() < 0.5 ? 1 : 2;
gameActive = true;
resultsDiv.textContent = `Player ${currentPlayer} (${currentPlayer === 1 ? "Cohere" : "Hugging Face"}) starts!`;
}
function isColumnFull(col) {
return board[0][col] !== 0;
}
function dropPiece(col, player) {
for (let r = rows - 1; r >= 0; r--) {
if (board[r][col] === 0) {
board[r][col] = player;
updateBoardUI(r, col, player);
return r;
}
}
return -1;
}
function updateBoardUI(row, col, player) {
const cell = document.querySelector(`.cell[data-row="${row}"][data-col="${col}"]`);
cell.classList.add(player === 1 ? "player1" : "player2");
}
function checkWinner(player) {
const directions = [
{ dr: 0, dc: 1 },
{ dr: 1, dc: 0 },
{ dr: 1, dc: 1 },
{ dr: 1, dc: -1 }
];
for (let r = 0; r < rows; r++) {
for (let c = 0; c < cols; c++) {
if (board[r][c] === player) {
for (const { dr, dc } of directions) {
let count = 0;
for (let i = 0; i < 4; i++) {
const nr = r + dr * i;
const nc = c + dc * i;
if (nr >= 0 && nr < rows && nc >= 0 && nc < cols && board[nr][nc] === player) {
count++;
}
}
if (count === 4) return true;
}
}
}
}
return false;
}
function makeMove() {
if (!gameActive) return;
const currentAPI = currentPlayer === 1 ? "Cohere" : "Hugging Face";
const fetchAI = currentPlayer === 1 ? fetchFromCohere : fetchFromHuggingFace;
fetchAI(board).then(col => {
if (!gameActive) return;
if (isColumnFull(col)) {
resultsDiv.textContent = `Player ${currentPlayer} (${currentAPI}) tried an invalid move. Skipping.`;
return setTimeout(switchPlayer, 250);
}
dropPiece(col, currentPlayer);
if (checkWinner(currentPlayer)) {
gameActive = false;
resultsDiv.textContent = `Player ${currentPlayer} (${currentAPI}) wins!`;
startButton.style.display = "none";
restartButton.style.display = "inline-block";
return;
}
setTimeout(switchPlayer, 250);
});
}
function switchPlayer() {
currentPlayer = 3 - currentPlayer;
makeMove();
}
async function fetchFromCohere(boardState) {
try {
// MH edit
console.log ( "Cohere send " + `Current board state:\n${JSON.stringify(boardState)}\nChoose a valid column (0-6) for your Connect 4 move:` );
const response = await fetch("https://api.cohere.ai/v1/generate", {
method: "POST",
headers: {
"Authorization": `Bearer ${COHERE_API_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
prompt: `Current board state:\n${JSON.stringify(boardState)}\nChoose a valid column (0-6) for your Connect 4 move:`,
max_tokens: 1,
temperature: 0.7
})
});
const result = await response.json();
// MH edit
console.log ( "Cohere response " ); console.log ( result );
const col = parseInt(result.generations[0]?.text.trim(), 10);
if (isNaN(col) || col < 0 || col > 6) {
throw new Error("Invalid move generated by Cohere");
}
return col;
} catch (error) {
console.error("Cohere error:", error);
return getRandomValidColumn();
}
}
async function fetchFromHuggingFace(boardState) {
try {
// MH edit
console.log ( "Hugging send " + `Current board state:\n${JSON.stringify(boardState)}\nChoose a valid column (0-6) for your Connect 4 move:` );
const response = await fetch("https://api-inference.huggingface.co/models/gpt2", {
method: "POST",
headers: {
"Authorization": `Bearer ${HUGGINGFACE_API_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify({ inputs: `Current board state:\n${JSON.stringify(boardState)}\nChoose a valid column (0-6) for your Connect 4 move:` })
});
const result = await response.json();
// MH edit
console.log ( "Hugging response " ); console.log ( result );
console.log ( result.generated_text );
console.log ( result[0].generated_text );
const col = parseInt(result.generated_text.trim(), 10);
if (isNaN(col) || col < 0 || col > 6) {
throw new Error("Invalid move generated by Hugging Face");
}
return col;
} catch (error) {
console.error("Hugging Face error:", error);
return getRandomValidColumn();
}
}
function getRandomValidColumn() {
// MH edit
console.log ("calling getRandomValidColumn");
const validColumns = [];
for (let c = 0; c < cols; c++) {
if (!isColumnFull(c)) validColumns.push(c);
}
return validColumns[Math.floor(Math.random() * validColumns.length)];
}
startButton.addEventListener("click", function () {
startButton.style.display = "none";
restartButton.style.display = "inline-block";
resultsDiv.textContent = "";
gameActive = true;
makeMove();
});
restartButton.addEventListener("click", function () {
gameActive = false;
startButton.style.display = "inline-block";
restartButton.style.display = "none";
initializeGame();
});
initializeGame();
});