使用python编写一个支持多用户的在线的康威的生命游戏,每个人可以创建最多10个活细胞,运行3轮后计算出存活的细胞数量作为得分,最后按得分排名

让用户通过点击一个 10x10 网格的表格来选择活细胞:

app.py

from flask import Flask, render_template, request, jsonify

app = Flask(__name__)

# 初始化玩家和游戏数据
players = {}
grid_size = 10  # 游戏网格大小

def create_empty_grid():
    return [[0 for _ in range(grid_size)] for _ in range(grid_size)]

def count_neighbors(grid, x, y):
    directions = [(-1, -1), (-1, 0), (-1, 1), (0, -1), (0, 1), (1, -1), (1, 0), (1, 1)]
    count = 0
    for dx, dy in directions:
        nx, ny = x + dx, y + dy
        if 0 <= nx < grid_size and 0 <= ny < grid_size:
            count += grid[nx][ny]
    return count

def run_generation(grid):
    new_grid = create_empty_grid()
    for x in range(grid_size):
        for y in range(grid_size):
            neighbors = count_neighbors(grid, x, y)
            if grid[x][y] == 1 and (neighbors == 2 or neighbors == 3):
                new_grid[x][y] = 1
            elif grid[x][y] == 0 and neighbors == 3:
                new_grid[x][y] = 1
    return new_grid

@app.route('/')
def index():
    return render_template('index.html', grid_size=grid_size)

@app.route('/register', methods=['POST'])
def register():
    username = request.json.get('username')
    if username in players:
        return jsonify({'error': 'Username already exists'}), 400
    players[username] = {
        'grid': create_empty_grid(),
        'score': 0
    }
    return jsonify({'message': 'User registered successfully'})

@app.route('/set_cells', methods=['POST'])
def set_cells():
    username = request.json.get('username')
    cells = request.json.get('cells')
    if username not in players:
        return jsonify({'error': 'User not found'}), 400
    if len(cells) > 10:
        return jsonify({'error': 'Too many cells'}), 400

    grid = create_empty_grid()
    for x, y in cells:
        grid[x][y] = 1
    players[username]['grid'] = grid
    return jsonify({'message': 'Cells set successfully'})

@app.route('/play', methods=['POST'])
def play():
    username = request.json.get('username')
    if username not in players:
        return jsonify({'error': 'User not found'}), 400

    grid = players[username]['grid']
    for _ in range(3):
        grid = run_generation(grid)
    players[username]['score'] = sum(sum(row) for row in grid)
    return jsonify({'score': players[username]["score"]})

@app.route('/leaderboard', methods=['GET'])
def leaderboard():
    scores = sorted(((username, data['score']) for username, data in players.items()), key=lambda x: x[1], reverse=True)
    return jsonify(scores)

if __name__ == '__main__':
    app.run(debug=True)

templates/index.html

<!DOCTYPE html>
<html>
<head>
    <title>Conway's Game of Life</title>
    <style>
        table {
            border-collapse: collapse;
        }
        td {
            width: 30px;
            height: 30px;
            border: 1px solid black;
            text-align: center;
            cursor: pointer;
        }
        .alive {
            background-color: green;
        }
    </style>
    <script>
        let username = "";
        let selectedCells = [];

        function toggleCell(x, y) {
            const cell = document.getElementById(`cell-${x}-${y}`);
            if (cell.classList.contains('alive')) {
                cell.classList.remove('alive');
                selectedCells = selectedCells.filter(([cx, cy]) => cx !== x || cy !== y);
            } else if (selectedCells.length < 10) {
                cell.classList.add('alive');
                selectedCells.push([x, y]);
            } else {
                alert("You can only select up to 10 cells!");
            }
        }

        async function register() {
            username = prompt("Enter your username:");
            const response = await fetch('/register', {
                method: 'POST',
                headers: { 'Content-Type': 'application/json' },
                body: JSON.stringify({ username })
            });
            if (response.ok) {
                alert("Registration successful!");
            } else {
                alert("Error: " + (await response.json()).error);
            }
        }

        async function setCells() {
            const response = await fetch('/set_cells', {
                method: 'POST',
                headers: { 'Content-Type': 'application/json' },
                body: JSON.stringify({ username, cells: selectedCells })
            });
            alert(await response.json().message);
        }

        async function play() {
            const response = await fetch('/play', {
                method: 'POST',
                headers: { 'Content-Type': 'application/json' },
                body: JSON.stringify({ username })
            });
            alert("Your score: " + (await response.json()).score);
        }

        async function leaderboard() {
            const response = await fetch('/leaderboard');
            const scores = await response.json();
            alert("Leaderboard:\n" + scores.map(([user, score]) => `${user}: ${score}`).join("\n"));
        }
    </script>
</head>
<body>
    <h1>Conway's Game of Life</h1>
    <button onclick="register()">Register</button>
    <button onclick="setCells()">Set Cells</button>
    <button onclick="play()">Play</button>
    <button onclick="leaderboard()">Leaderboard</button>
    <h2>Click to select up to 10 live cells:</h2>
    <table>
        <tbody>
            {% for x in range(grid_size) %}
            <tr>
                {% for y in range(grid_size) %}
                <td id="cell-{{x}}-{{y}}" onclick="toggleCell({{x}}, {{y}})"></td>
                {% endfor %}
            </tr>
            {% endfor %}
        </tbody>
    </table>
</body>
</html>

说明

  1. 在前端生成了一个 10x10 的表格,用户点击单元格即可选择活细胞,最多 10 个。
  2. 使用 toggleCell 方法动态添加或移除选中的细胞,限制为 10 个。
  3. 表格的每个单元格的点击事件会改变其样式(变为绿色表示活细胞)。
  4. 后端逻辑保持不变,接收选中的细胞列表进行游戏计算。

运行后用户可以通过直观的表格点击方式选择细胞。

Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐