「开发日记」GPT帮我完成了无痛开发!拖拽24点小游戏开发对话记录大赏

256 阅读4分钟

前因后果

如今,AI显然已经成为了我生活中不可或缺的一部分。突发奇想,使用AI做一个24点小游戏未尝不可。

作为一名热爱捣腾的人,我也开始了探索AI编程的旅程。虽然不能完全取代人类的创造力和想象力,但是它所提供的帮助,却让这个折腾来的更加自如和高效。

现把我跟AI交互全过程展现给大家。

交互记录

一共分为两个版本,第一版是一个错误的结果,也可以借鉴其中的Prompt,避坑。

第一版

第一版的过程很是曲折:

起初,它看起来是一个蛮贴心的开发者,会问的很细致。

image.png image.png

它正确的输出了HTML、CSS、JS。

但是因为长度限制,JS还未输出完,所以“继续”。

这时候虽然样式错了,但也不影响代码运行。

BUT初始的代码中有BUG:

image.png

接下来就要进入无限循环,可能是由于历史记录限制(?)GPT认为自己的上一段输出的代码不完整,所以开始从HTML开始输出代码,这就导致了,每次都无法生成完全。

比如,我即便是这样跟它说:

它依然从HTML开始输出了,所以我又换了另外一种说法:

它不管我,只管自顾自的严苛要求自己重写HTML。

所以我又又又换了一种说法:

它已经不听使唤了。

最后尝试一次。

效果截屏

这是第一版的效果,拖拽没问题,拖拽到哪里是个问题。

代码文件

代码也放在下面了,请各位看官自lo

index.html

<!DOCTYPE html>
<html>
  <head>
    <title>24点游戏</title>
    <link rel="stylesheet" href="style.css" />
  </head>
  <body>
    <div id="card-container">
      <div class="card" draggable="true">1</div>
      <div class="card" draggable="true">2</div>
      <div class="card" draggable="true">3</div>
      <div class="card" draggable="true">4</div>
    </div>
    <div id="result-container">
      <button id="check-button">检查</button>
      <div id="result"></div>
    </div>
    <script src="app.js"></script>
  </body>
</html>

app.js

// 获取卡牌容器和结果容器
const cardContainer = document.getElementById('card-container');
const resultContainer = document.getElementById('result-container');

// 获取卡牌和检查按钮
const cards = document.querySelectorAll('.card');
const checkButton = document.getElementById('check-button');

// 定义当前选中的卡牌和结果
let selectedCards = [];
let result = '';

// 定义拖拽事件处理函数
function handleDragStart(e) {
  e.dataTransfer.setData('text/plain', e.target.textContent);
  e.target.classList.add('dragging');
}

function handleDragOver(e) {
  e.preventDefault();
}

function handleDrop(e) {
  e.preventDefault();
  const cardValue = e.dataTransfer.getData('text/plain');
  const card = document.createElement('div');
  card.textContent = cardValue;
  card.classList.add('card');
  cardContainer.insertBefore(card, e.target.nextSibling);
  e.target.remove();
  card.classList.remove('dragging');
  selectedCards = Array.from(cards).map((card) => Number(card.textContent));
}

// 绑定拖拽事件处理函数
cards.forEach((card) => {
  card.addEventListener('dragstart', handleDragStart);
  card.addEventListener('dragover', handleDragOver);
  card.addEventListener('drop', handleDrop);
});

// 定义检查结果函数
function checkResult() {
  // 判断是否选中了4张卡
  if (selectedCards.length !== 4) {
    result = '请选择4张卡牌';
  } else {
    // 计算结果是否为24
    const a = selectedCards[0];
    const b = selectedCards[1];
    const c = selectedCards[2];
    const d = selectedCards[3];
    if (a + b + c + d === 24) {
      result = '胜利!';
    } else {
      result = '失败,请重新选择卡牌';
    }
  }
  // 显示结果
  document.getElementById('result').textContent = result;
}

// 绑定检查按钮事件处理函数
checkButton.addEventListener('click', checkResult);

style.css

body {
  background-color: white;
}

#card-container {
  display: flex;
  justify-content: space-between;
  margin: 50px auto;
  width: 400px;
}

.card {
  background-color: lightgray;
  border: 1px solid gray;
  border-radius: 5px;
  box-sizing: border-box;
  cursor: pointer;
  font-size: 32px;
  height: 100px;
  line-height: 100px;
  text-align: center;
  user-select: none;
  width: 80px;
}

#result-container {
  text-align: center;
}

#check-button {
  background-color: lightblue;
  border: none;
  border-radius: 5px;
  color: white;
  cursor: pointer;
  font-size: 24px;
  margin-bottom: 10px;
  padding: 10px 20px;
}

#result {
  font-size: 32px;
  font-weight: bold;
  margin-top: 20px;
}

第二版

对话记录

吸取了第一次无限循环的教训,这次,开始就告诉它要怎么生成:

它比较正确的给出了HTML。

CSS和JS代码也顺利地生成了。

效果截屏

这次的就比较符合要求了。

代码文件

第二版的代码也放在下面了,请各位看官自取

index.html

<!DOCTYPE html>
<html>
  <head>
    <title>24点游戏</title>
    <link rel="stylesheet" type="text/css" href="style.css" />
  </head>
  <body>
    <div id="initial-area" class="card-area">
      <h2>初始区</h2>
      <div class="card" draggable="true" ondragstart="drag(event)">1</div>
      <div class="card" draggable="true" ondragstart="drag(event)">2</div>
      <div class="card" draggable="true" ondragstart="drag(event)">3</div>
      <div class="card" draggable="true" ondragstart="drag(event)">4</div>
      <div class="card" draggable="true" ondragstart="drag(event)">5</div>
      <div class="card" draggable="true" ondragstart="drag(event)">6</div>
      <div class="card" draggable="true" ondragstart="drag(event)">7</div>
      <div class="card" draggable="true" ondragstart="drag(event)">8</div>
      <div class="card" draggable="true" ondragstart="drag(event)">9</div>
      <div class="card" draggable="true" ondragstart="drag(event)">10</div>
      <div class="card" draggable="true" ondragstart="drag(event)">J</div>
      <div class="card" draggable="true" ondragstart="drag(event)">Q</div>
      <div class="card" draggable="true" ondragstart="drag(event)">K</div>
      <div class="card" draggable="true" ondragstart="drag(event)">A</div>
      <div class="card" draggable="true" ondragstart="drag(event)">2</div>
      <div class="card" draggable="true" ondragstart="drag(event)">Joker</div>
      <div class="card" draggable="true" ondragstart="drag(event)">Joker</div>
    </div>
    <div
      id="selected-area"
      class="card-area"
      ondrop="drop(event)"
      ondragover="allowDrop(event)"
    >
      <h2>选择区</h2>
    </div>
    <div id="button-area">
      <button onclick="reset()">重置</button>
      <button onclick="check()">检查</button>
    </div>
    <div id="result-area">
      <h2 id="result"></h2>
    </div>
    <script src="script.js"></script>
  </body>
</html>

script.js

var selectedCards = [];

function drag(event) {
  event.dataTransfer.setData('text', event.target.innerText);
}

function allowDrop(event) {
  event.preventDefault();
}

function drop(event) {
  event.preventDefault();
  var data = event.dataTransfer.getData('text');
  event.target.innerHTML +=
    "<div class='card selected-card'>" + data + '</div>';
  event.target.lastChild.setAttribute('draggable', 'false');
  selectedCards.push(data);
  var initialArea = document.getElementById('initial-area');
  initialArea.removeChild(initialArea.lastChild);
}

function reset() {
  var selectedArea = document.getElementById('selected-area');
  selectedArea.innerHTML = '<h2>选择区</h2>';
  selectedCards = [];
  var initialArea = document.getElementById('initial-area');
  initialArea.innerHTML =
    "<h2>初始区</h2><div class='card' draggable='true' ondragstart='drag(event)'>1</div><div class='card' draggable='true' ondragstart='drag(event)'>2</div><div class='card' draggable='true' ondragstart='drag(event)'>3</div><div class='card' draggable='true' ondragstart='drag(event)'>4</div><div class='card' draggable='true' ondragstart='drag(event)'>5</div><div class='card' draggable='true' ondragstart='drag(event)'>6</div><div class='card' draggable='true' ondragstart='drag(event)'>7</div><div class='card' draggable='true' ondragstart='drag(event)'>8</div><div class='card' draggable='true' ondragstart='drag(event)'>9</div><div class='card' draggable='true' ondragstart='drag(event)'>10</div><div class='card' draggable='true' ondragstart='drag(event)'>J</div><div class='card' draggable='true' ondragstart='drag(event)'>Q</div><div class='card' draggable='true' ondragstart='drag(event)'>K</div><div class='card' draggable='true' ondragstart='drag(event)'>A</div><div class='card' draggable='true' ondragstart='drag(event)'>2</div><div class='card' draggable='true' ondragstart='drag(event)'>Joker</div><div class='card' draggable='true' ondragstart='drag(event)'>Joker</div>";
}

function check() {
  if (selectedCards.length !== 4) {
    document.getElementById('result').innerHTML = '请选择4张牌';
    return;
  }
  var permutations = permute(selectedCards);
  var expressions = generateExpressions(permutations);
  var result = false;
  var expression = '';
  for (var i = 0; i < expressions.length; i++) {
    var value = eval(expressions[i]);
    if (value === 24) {
      result = true;
      expression = expressions[i];
      break;
    }
  }
  if (result) {
    document.getElementById('result').innerHTML =
      '恭喜您,成功!<br>' + expression + '= 24';
  } else {
    document.getElementById('result').innerHTML = '很遗憾,失败!';
  }
}

function permute(arr) {
  var result = [];
  if (arr.length === 0) {
    return result;
  }
  if (arr.length === 1) {
    result.push(arr);
    return result;
  }
  for (var i = 0; i < arr.length; i++) {
    var first = arr[i];
    var rest = arr.slice(0, i).concat(arr.slice(i + 1));
    var permutations = permute(rest);
    for (var j = 0; j < permutations.length; j++) {
      var permutation = [first].concat(permutations[j]);
      result.push(permutation);
    }
  }
  console.log({ result });
  return result;
}

function generateExpressions(permutations) {
  var operators = ['+', '-', '*', '/'];
  var expressions = [];
  for (var i = 0; i < permutations.length; i++) {
    var permutation = permutations[i];
    for (var j = 0; j < operators.length; j++) {
      var operator1 = operators[j];
      for (var k = 0; k < operators.length; k++) {
        var operator2 = operators[k];
        for (var l = 0; l < operators.length; l++) {
          var operator3 = operators[l];
          var expression =
            permutation[0] +
            operator1 +
            permutation[1] +
            operator2 +
            permutation[2] +
            operator3 +
            permutation[3];
          expressions.push(expression);
        }
      }
    }
  }
  console.log({ expressions });
  return expressions;
}

style.css

.card-area {
  border: 1px solid black;
  padding: 10px;
  margin: 10px;
  display: inline-block;
  vertical-align: top;
}

.card {
  border: 1px solid black;
  width: 50px;
  height: 70px;
  text-align: center;
  line-height: 70px;
  margin: 5px;
  display: inline-block;
  background-color: white;
}

.card:hover {
  cursor: pointer;
  background-color: #f2f2f2;
}

.selected-card {
  background-color: #b3d9ff;
}