1/3
2 Years of Service
famous last quoteI mean, I had to use the time down there on something useful...
And dooon't worry, she's... friieendly?...
famous last quoteI mean, I had to use the time down there on something useful...
And dooon't worry, she's... friieendly?...
I usedYou must be registered to see linksand you're probably right that there's better AI code generation platforms. But I don't know them, so I just used what came up. It wasn't meant to be a definitive test either.
It does what it's supposed to do well enough, but the main problem I'm thinking of are always A. Readability and B. Integration into overall code. Using RPG Maker MZ's "specific" code I'm pretty used to run into the weird ways how code that I have to integrate & alias into works.
So since implementation of one thing often mandates specific implementation elsewhere, that's always a key worry for me.
The code the AI has generated has me a little stumped. It's first of all not working. The issue seems to be that it's actually trying to hand over the gameboard itself *during* the construction process.
JavaScript:// Function to create a gameboard function createGameboard(rows, cols) { const gameboard = Array.from({ length: rows }, (_, row) => Array.from({ length: cols }, (_, col) => new Card(row, col, gameboard)) ); // Assign the gameboard reference after creation gameboard.forEach(row => row.forEach(card => card.gameboard = gameboard)); return gameboard; }
As the "new Card" is created, the function tries to pass the gameboard to that card, which is impossible, because the new card is created during the construction process of the gameboard, so it doesn't exist yet.
Likewise, the gameboard still creates rows into seperate arrays.
Here's the solution how I'd design it (plus an added Wall)
I create a Wall object which will be returned with predefined values whenever we don't have a neighbor. (Can be used for Wall mechanics, e.g. Triple Triad).JavaScript:class Wall { constructor() { } values() { return [9,9,9,9] } } class Card { constructor(values) { this._values = values; } values() { return this._values; } getOwnPosition() { const index = $GameBoard.tiles().findIndex(card => card === this); const row = Math.floor(index / $GameBoard.width); const column = index % $GameBoard.width; return {row, column, index} } leftNeighbor() { const pos = this.getOwnPosition(); if (pos.column === 0) { return new Wall(); } return $GameBoard.tiles()[pos.index - 1]; } rightNeighbor() { const pos = this.getOwnPosition(); if (pos.column === $GameBoard.width - 1) { return new Wall(); } return $GameBoard.tiles()[pos.index + 1]; } topNeighbor() { const pos = this.getOwnPosition(); if (pos.row === 0) { return new Wall(); } return $GameBoard.tiles()[pos.index - $GameBoard.width]; } bottomNeighbor() { const pos = this.getOwnPosition(); if (pos.row === $GameBoard.height - 1) { return new Wall(); } return $GameBoard.tiles()[pos.index + $GameBoard.width]; } } class Gameboard { constructor(width, height) { this.width = width; this.height = height; this.createTiles(); } tiles() { return this._tiles; } createTiles() { this._tiles = []; for (let i = 1; i <= this.width * this.height; i++) { this.addCardToSlot(); } } addCardToSlot() { const min = 1; const max = 9; const values = Array.from({ length: 4 }, () => this.createRandomNumber(min, max)) this._tiles.push(new Card(values)); } createRandomNumber(min, max) { return Math.floor((Math.random() * (max - min + 1))) + min; } } // Create Board const $GameBoard = new Gameboard(3, 3); // Neighbor example // retrieves the values of the card above the fourth card (row 2, column 1) console.log($GameBoard.tiles()[3].topNeighbor().values)
This is basically just a gimmick addition, the computer should in the prompt always return "null" (meaning no tile), whereas I decided to hand over the wall.
Then I create the Card Object. This is created with external values, so if I instead of random values wanted to retrieve values from a DB (e.g. a Card Database) I can integrate this easily.
Values is used to always get the cards values (.e.g Triple Triad Card Attack values).
getOwnPosition hands back an object with this card's location data that is dynamically generated. If I simply switch to cards in the main array, the position will automatically update without any further input from me.
The Neighbor checks simply get my own tile's data from the gameboard, then check if there cannot be a Neighbor. (In which case I hand back the Wall)
If it's not a wall, it calculates the correct card index based on the width of the game board and hands me those values.
The Gameboard is pretty simple in its generation.
Some of the advantages present here is that I can access all of the boards tiles through the $GameBoard.tiles() method and don't have to deal with multiple subarrays inside an array.
The Gameboard's position data is always right, the Neighbors always correct, even should the Board for some reason change in size.
While this version is slower (due to retrieving values & doing calculations instead of just picking up pre-defined values), it's very robust. Parameters can be changed easily, and everything still works. It also has a, in my opinion, much more coherent and readable structure, which means the code is much easier to edit & maintain.
class Wall {
constructor() {}
values() {
return [9, 9, 9, 9];
}
}
class Card {
constructor(values) {
this._values = values;
}
values() {
return this._values;
}
getPosition() {
const index = $GameBoard.tiles().indexOf(this);
const row = Math.floor(index / $GameBoard.width);
const column = index % $GameBoard.width;
return { row, column, index };
}
neighbor(direction) {
const { row, column, index } = this.getPosition();
switch (direction) {
case 'left':
return column > 0 ? $GameBoard.tiles()[index - 1] : new Wall();
case 'right':
return column < $GameBoard.width - 1 ? $GameBoard.tiles()[index + 1] : new Wall();
case 'top':
return row > 0 ? $GameBoard.tiles()[index - $GameBoard.width] : new Wall();
case 'bottom':
return row < $GameBoard.height - 1 ? $GameBoard.tiles()[index + $GameBoard.width] : new Wall();
default:
return null;
}
}
leftNeighbor() {
return this.neighbor('left');
}
rightNeighbor() {
return this.neighbor('right');
}
topNeighbor() {
return this.neighbor('top');
}
bottomNeighbor() {
return this.neighbor('bottom');
}
}
class Gameboard {
constructor(width, height) {
this.width = width;
this.height = height;
this._tiles = this.createTiles();
}
tiles() {
return this._tiles;
}
createTiles() {
return Array.from({ length: this.width * this.height }, () => this.createCard());
}
createCard() {
const values = Array.from({ length: 4 }, () => this.createRandomNumber(1, 9));
return new Card(values);
}
createRandomNumber(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
}
}
// Create Board
const $GameBoard = new Gameboard(3, 3);
// Neighbor example
// Retrieves the values of the card above the fourth card (row 1, column 0)
console.log($GameBoard.tiles()[3].topNeighbor().values());
Took me a awhile to respond.
AI is much faster, that's true. The most useful cases I can imagine is when a programmer wants to know the method of how something is done, rather than a specific complete implementation of a part of the code.
The second version of the AI you posted is at least a lot more readable, and the use of the Array.from method is pretty curious enough that I used it myself rather than creating a for loop iteration & pushing values.
Time to set off
You must be registered to see attachments
In case I dont see ya
![]()
Hiya bonky!
You must be registered to see attachments
You must be registered to see attachments
Although lemme tell ya about pencils...
I hope you enjoyed your time off and had some fun! I need to put in for some time off soonYou must be registered to see attachments
And invest in Bonkcoin, soon to be the dominant currency globally
You must be registered to see attachments
I had to go back today after having 7 of the last 9 days off. Hang in there man
Ok, calm down, that's kinda seriousThe point re: this website's situation?
Personally, I'm assuming the team can't talk much about it because they can't, or they think it'll make it worse.
And then... the bullshit speculation begins... because that's happens when human nature meets a secret...
Yeah, how about you start learning french and add some activity there!
![]()
Ok, calm down, that's kinda serious
guys, when we say 'we can't talk much,' it's because a lot of things are still being discussed, staff things, y'know? Like, people keep asking me if AI will be banned forever, I can't say yes or no because that was never discussed, but I assure you, we have no problems with laws. The report was dealt with and we're okay, our actions were to prevent further problems and reports. Let me be 100% clear because I don't want to be asked this again, the only thing that prevents us from saying literally everything about our situation and staff meetings is our positions as staff members. No investigations, no lawyers, nothing
at least half of u say otherwise '-'I will be your Lawyer!
I'm remarkably calm and collected.
You must be registered to see attachments
Haha. I am sure it'd also be better if you were talking to it directly, ratherr than second-hand through me. Because you'd explain the needs a lot better, I guess.
But still, I decided to share your message to 4o to see what it says!
JavaScript:class Wall { constructor() {} values() { return [9, 9, 9, 9]; } } class Card { constructor(values) { this._values = values; } values() { return this._values; } getPosition() { const index = $GameBoard.tiles().indexOf(this); const row = Math.floor(index / $GameBoard.width); const column = index % $GameBoard.width; return { row, column, index }; } neighbor(direction) { const { row, column, index } = this.getPosition(); switch (direction) { case 'left': return column > 0 ? $GameBoard.tiles()[index - 1] : new Wall(); case 'right': return column < $GameBoard.width - 1 ? $GameBoard.tiles()[index + 1] : new Wall(); case 'top': return row > 0 ? $GameBoard.tiles()[index - $GameBoard.width] : new Wall(); case 'bottom': return row < $GameBoard.height - 1 ? $GameBoard.tiles()[index + $GameBoard.width] : new Wall(); default: return null; } } leftNeighbor() { return this.neighbor('left'); } rightNeighbor() { return this.neighbor('right'); } topNeighbor() { return this.neighbor('top'); } bottomNeighbor() { return this.neighbor('bottom'); } } class Gameboard { constructor(width, height) { this.width = width; this.height = height; this._tiles = this.createTiles(); } tiles() { return this._tiles; } createTiles() { return Array.from({ length: this.width * this.height }, () => this.createCard()); } createCard() { const values = Array.from({ length: 4 }, () => this.createRandomNumber(1, 9)); return new Card(values); } createRandomNumber(min, max) { return Math.floor(Math.random() * (max - min + 1)) + min; } } // Create Board const $GameBoard = new Gameboard(3, 3); // Neighbor example // Retrieves the values of the card above the fourth card (row 1, column 0) console.log($GameBoard.tiles()[3].topNeighbor().values());
Changes Made:
- Consistent Method Naming: Renamed getOwnPosition to getPosition and addCardToSlot to createCard for consistency and clarity.
- Optimised getPosition: Used indexOf directly to find the card's position without iterating through the tiles twice.
- Simplified Neighbour Methods: Combined the boundary check and neighbour fetching logic into a single neighbor method to reduce redundancy.
- Array Creation Simplification: Used Array.from to create the tiles array directly in the createTiles method.
AI is definitely quicker! 4o is SO fast. But, a case of Slow and Steady, I think. Speed is definitely good sometimes, but not if it has errors inside.
All this said, I'm still very much an amateur coder - but my friend, who makes a (very good) living as a developer. Recently used 4o for the first time and was really impressed by what he got out of it. So, it could all just come down to utilisation. At the end of the day, I think it's a tool and a resource like so many others. It's also quite good at optimisation - when you give it some code you've already written and it says "You're wasting a lot of time doing this..." .... Or maybe that's just the way I code.... haha
Good afternoon !Good afternoon/evening everyone!
You must be registered to see attachments
The changes are interesting, though a mixed bag.
Is not ideal. I wouldn't use getPosition instead of getOwnPosition, because the latter is clearer and ensures that you know it doesn't require inputs. getPosition is also not ideal because it's a bit unspecific. In hindsight, a better function name would be getOwnTilePosition. That's because the very specific nature of it would mean I'm not going to get relinked to sprite objects that may have getPosition or getOwnPosition in order to retrieve x & y values, thereby making the management of the code better.
I'd disagree vehemently with createCard instead of addCardToSlot, because the former makes it a lot clearer what's actually happening, while the latter leaves the developer uninformed that a card isn't just magically created but placed in a slot.
Two is actually an improvement. I was a bit in a hurry and so used findIndex, which requires me to use a function as identifying method, when I can just use indexOf to do the same, slightly faster and more cleaner.
The boundary check combination isn't necessary, but I actually like it optically more. It's also good that the idea left the original methods intact to still allow a specific direct function without arguments to retrieve the tiles. All in all a good change.
4 is actually a big mistake in how the function works. That's a blunder.
The original function is capable of creating an array & filling it simply by using $Gameboard.createTiles(). However, the new one is not capable of filling the tiles but instead just returns an array of tiles. In other words, should I wish to clean the tiles and populate them with new cards, I originally could just use the just mentioned createTiles() function, while now that function won't do anything. The tiles can now ONLY be populated at creation, thereby limiting the functionality without any benefits.
As I said, a mixed bag - but still pretty interesting. Do you need to have some kind of registration or payment or something to access that AI? Or is it publicly available?
Hi brother Mono, didn't know you were here....just getting my bear-ings straight
You must be registered to see attachments
And i don't know about Conzi, but i might take a stab at slumthing
Heh. Believe it or not, that WAS me being calm.Ok, calm down, that's kinda serious
guys, when we say 'we can't talk much,' it's because a lot of things are still being discussed, staff things, y'know? Like, people keep asking me if AI will be banned forever, I can't say yes or no because that was never discussed, but I assure you, we have no problems with laws. The report was dealt with and we're okay, our actions were to prevent further problems and reports. Let me be 100% clear because I don't want to be asked this again, the only thing that prevents us from saying literally everything about our situation and staff meetings is our positions as staff members. No investigations, no lawyers, nothing
Wait what???? You and @Slumdum broke up? Wtf you two were so beautiful togetherWas ok til a few minutes ago. I think i got dumped but .....mixed signals ya know
Hello, I'm Bonky and this is my first day as well. It's nice to meet you IIIIIIIIII
You must be registered to see attachments
This site provides links to other sites/services, and does not store any files