< Vindinium Jenna Wu-Cardona

Jenna Wu-Cardona

Vindinium

Full Vindinium Screen

Overall
vindinium title

Vindinium is a multiplayer artificial intelligence game in which players create a bot and code its instructions in Javascript. Each round, there’s a random setting comprised of foliage and water, mines, and taverns. Players begin with 100 health points and zero gold. Every player’s goal is to end the game with the most amount of gold, which is gotten by collecting mines, which give the owner one piece of gold per turn. To collect mines, players have to defeat a goblin, which protects it. They can also gain mines from killing other players, which gives them all of the deceased’s mines. When a player is killed, they keep all their gold, but have no mines. Taverns give players more health, at 50 health points for two coins.

Part 1
vindinium 1

This section was given to us already coded, but I'll still describe lines 3 and 4, which I did use. These are basically the same thing, but one is commented out. The random string first in the parentheses is my bot's code, which means that you could take it and use my bot. The training/arena part determines whether or not my bot pretty much just tests for if it crashes (training) or runs against other bots (arena). Lastly, the http://vindinium.org/http://52.39.33.197:9000 determines if my bot runs against the main Vindinium server (vindinium.org) or the private server for this class (52.39.33.197:9000).

Part 2- Global Data

Title and myDir This shows the introduction of the Global Data section and writes myDir. There is a variable made called myPos which holds the x and y coordinates of my bot.

Global Data- Enemy Bots This enemy bots array determines who the enemies are by asking if my bot is enemy bot 1, then going down the line. It then pushes the enemy bots into an array called enemyBots so that it can be accessed later all together.

Global Data- All Mines This code makes an array for all of the mines called allMines. It has the position of the enemy mines in the lines 31, 32, and 33.

Global Data- Closest Player This code determines where the closest player is. This is used with other code (described later) to attack other players.

Part 3- WHAT to do

Title and taverns This code is the title of the what to do section and includes the taverns if statement. It sets a variable called task, which holds all of the following statements (taverns, attack, and freeMines). It then has an if statement, the condition of which says that if my bot's health is < 51 points, it should run the code block, which tells the how to do it part that that's what should be done. I used the bot.yourBot.life id, which says the health.

what to do- attack Second is the attack function. This is an else if statement, which means that if the taverns task can't run, it checks if this can run. This condition says that if my position is < 4 positions away, the task "attack" should run. This is run from the how to do it page, which will soon be explained. I used the array that I had made in the global data section that tells where the closest player is to find the position of the other player.

what to do- free mines This last statement is an else statement. That means that if neither of the two functions before can run, this gets run. It cues the task "freeMines" which will be described in the how to do it page.

Part 4- HOW to do it

Title and mines This picture begins with the title of the How-to-do-it section. It also includes the freeMines task in an if statement. It says that if freeMines is run, then find the closest free mine and taken mine. It then compares the two and if the nearest taken mine is closer than the nearest free mine, it changes that to closestMine. Then it sends the bot to that position and makes the console (the description when you can't see the tv of the game) say, "Claiming a Mine!"

How to do it- taverns code This code says that if the task from the what-to-do section was taverns, then run this code. This is very similar to the mines section. It says that if taverns is run, to look in the bot.taverns array that holds where all of the taverns are, find the nearest tavern, and set myDir to it. The console log then says, "Closest tavern", which is boring but it's just so that I know where it's going and what it's doing.

How to do it- attack code This code says that if the task from the what-to-do section was "attack" it runs this. It sets myDir on the path towards the closest player, which was found in the closestPlayer array in the global data section. Then, it says, "Attacking!" in the console.

How to do it- stay still code This section wasn't written by me (it was given to us), so I won't thoroughly explain it, other than that it makes my bot go random. I don't know why I would want it to go random, but looking at the console log, it happens more than I would think.

What I Learned

This was a very hard project, especially the first couple days we were doing it. I had absolutely no idea what I was doing and was super confused, even when people explained how to do things. I first started understanding how it worked when Mr. Hesby did the attack function (or some other function, I don't remember) on the board and people could follow along and copy what he was writing. Even though this could be considered cheating and might not help some people, it was very informational for me because I began to understand how the three sections work together and how most of the sections (going to taverns, mines, or attacking people) aren't that different from each other.

I don't and didn't really know what I wanted my bot to do, mostly because I didn't understand Vindinium at first, but once I understood a little, I knew I had to make my bot be able to go to taverns, free mines, enemy mines, and other players to attack. I remember wanting my bot to be able to go to enemy mines, and I eventually learned how and did it, after some effort. I don't really know what else I could add to a bot, other than just being more detailed about attacking other players when they have the most mines, for instance, so therefore I am satisfied with my bot.

I learned a medium amount about AI in this block, too. I kept on thinking it said Al at first (that's a lowercase L, by the way), and I was like, "What's al?" That's part of what I learned about AI: that it's not someone's nickname. I also learned that EVERY SINGLE THING needs to be coded, because bots are very dumb without it. I know that I will appreciate artificial intelligence much more than I did before this project.

All Code

       
           var Bot = require('bot');
var PF = require('pathfinding');
// var bot = new Bot('ger0yqw7', 'training', 'http://vindinium.org'); /*Put your bot's code here and change training to Arena when you want to fight others.*/
var bot = new Bot('smzyd7pm', 'arena', 'http://52.39.33.197:9000'); /*Put your bot's code here and change training to Arena when you want to fight others.*/
var goDir;
var Promise = require('bluebird');
Bot.prototype.botBrain = function() {
    return new Promise(function(resolve, reject) {
        _this = bot;
        //////* Write your bot below Here *//////
        //////* Set `myDir` in the direction you want to go and then bot.goDir is set to myDir at the bottom *////////

        /*                                      *
         * This Code is global data!            *
         *                                      */

        // Set myDir to what you want and it will set bot.goDir to that direction at the end.  Unless it is "none"
        var myDir;
        var myPos = [bot.yourBot.pos.x, bot.yourBot.pos.y];


        /* enemyBots [] holds [x,y] of enemy bots */
        var enemyBots = [];
        if (bot.yourBot.id != 1) enemyBots.push(bot.bot1);
        if (bot.yourBot.id != 2) enemyBots.push(bot.bot2);
        if (bot.yourBot.id != 3) enemyBots.push(bot.bot3);
        if (bot.yourBot.id != 4) enemyBots.push(bot.bot4);

        /* allMines [] holds [x,y] of each enemy mines. The for loop pushes all of the locations of the free mines into the array*/
        var allMines = [];
        allMines = allMines.concat(enemyBots[0].mines);
        allMines = allMines.concat(enemyBots[1].mines);
        allMines = allMines.concat(enemyBots[2].mines);
        for (i = 0; i < bot.freeMines.length; i++) {
            allMines.push(bot.freeMines[i]);
        }

        /*  variable closestPlayer holds the array of enemyBots. enemyBots holds */
        var closestPlayer = enemyBots[0];
        for (i = 0; i < bot.enemyBots.length; i++) {
            if (bot.findDistance(myPos, closestPlayer.posArray) > bot.findDistance(myPos, bot.enemyBots[i].posArray)) {
                closestPlayer = bot.enemyBots[i];
            }
        }

        /*                                      *
         * This Code Decides WHAT to do         *
         *                                      */
        //variable task
        var task;
        //run taverns if bot health <51
        if (bot.yourBot.life < 51) {
            task = "taverns";
        }

        //run attack if taverns cant be run and my position is < 4 from closest enemy
        else if (bot.findDistance(myPos, closestPlayer.posArray) < 4) {
            task = "attack";
        }

        //run freeMines if previous if conditions are false
        else {
            task = "freeMines";
        }

        /*                                      *
         * This Code Determines HOW to do it    *
         *                                      */
        // This Code find the nearest freemine, sets myDir to that path, and goes there
        if (task === "freeMines") {
            var closestMine = bot.freeMines[0];
            for (i = 0; i < allMines.length; i++) {
                if (bot.findDistance(myPos, closestMine) > bot.findDistance(myPos, allMines[i])) {
                    closestMine = allMines[i];
                }
            }
            console.log("Claiming a Mine!");
            myDir = bot.findPath(myPos, closestMine);
        }

        //this finds the nearest freeTavern, sets myDir to that path//
        if (task === "taverns") {
            var closestTavern = bot.taverns[0];
            for (i = 0; i < bot.taverns.length; i++) {
                if (bot.findDistance(myPos, closestTavern) > bot.findDistance(myPos, bot.taverns[i])) {
                    closestTavern = bot.taverns[i];
                }
            }
            console.log("Closest tavern");
            myDir = bot.findPath(myPos, closestTavern);
        }

        // This Code find the nearest player and sets myDir toward that direction to attack //
        if (task === "attack") {
            console.log("Attacking!");
            myDir = bot.findPath(myPos, closestPlayer.posArray);
        }

        /* Sets your direction based on myDir. If you are trying to go to a place that you can't reach, you move randomly.*
         * Otherwise you move in the direction set by your code.  Feel free to change this code if you want.*/
        if (myDir === "none") {
            console.log("Going Random!");
            var rand = Math.floor(Math.random() * 4);
            var dirs = ["north", "south", "east", "west"];
            bot.goDir = dirs[rand];
        }
        else {
            bot.goDir = myDir;
        }

        ///////////* DON'T REMOVE ANTYTHING BELOW THIS LINE *//////////////
        resolve();
    });
}
bot.runGame();