[Add-On]Minesweeper NPC

Joined
Apr 10, 2009
Messages
91
Reaction score
195
I was bored so I made a Minesweeper NPC:
PHP:
/** Minesweeper NPC
 *  Author: Emilyx3 of UMaple
 */
var DEBUG = false;
var HIDDEN_ITEM = 4031325, MINE_ITEM = 5021013, EXPLODED_ITEM = 5120009;
var Modes = [
    //MAX COL = 7
    //MAX ROW = 7 (Without scrolling)
    //Difficulty Name, Rows, Cols, Number of Mines
    ["#gEasy                 #k", 5, 5, 4],
    ["#bIntermediate   #k", 6, 6, 8],
    ["#rHard                 #k", 7, 7, 15]
];

/* Don't touch these variables below unless you know what you're doing */
var status;
var Board, Revealed;
var VALUE_REVEALED = 1, VALUE_HIDDEN = 0;
var ModeSelected = -1, StartTime = -1, NumCols = -1,
NumRows = -1, NumMines = -1, LeftToBeRevealed = -1;
var Neighbors = [
    //dX ,dY
    [-1, -1], [-1, 0], [-1, 1], [0, -1],
    [0, 1],   [1, -1], [1, 0],  [1, 1]
];
var Numbers = [
3990009, 3990000, 3990001, 3990002, 3990003,
3990004, 3990005, 3990006, 3990007, 3990008
];
/* Don't touch these variables above unless you know what you're doing */

function start() {
    status = -1;
    action(1, 0, 0);
}
function Header() {
    return "#d============ Minesweeper ============#k\r\n\r\n";
}
function ConstructModeSelectionString() {
    var ret = "";
    for (var i = 0;i < Modes.length;i++) {
        ret += "#L"+i+"#"+Modes[i][0]+" ("+Modes[i][1]+"x"+Modes[i][2]+") Mines: "+Modes[i][3]+"#l\r\n";
    }
    return ret;
}
function InitializeBoard() {
    NumCols = Modes[ModeSelected][1];
    NumRows = Modes[ModeSelected][2]
    NumMines = Modes[ModeSelected][3];
    LeftToBeRevealed = NumCols * NumRows - NumMines;
    Board = new Array(NumCols);
    for (var i = 0;i < NumCols;i++) {
        Board[i] = new Array(NumRows);
    }
    Revealed = new Array(NumCols);
    for (i = 0;i < NumCols;i++) {
        Revealed[i] = new Array(NumRows);
        for (var j = 0;j < NumRows;j++) {
            Revealed[i][j] = VALUE_HIDDEN;
        }
    }
    InitializeMines();
    InitializeMineCounts();
    InitializeBlankSpaces();
}
function InitializeMines() {
    var AllPosition = new Array(NumRows * NumCols);
    for (var i = 0;i < NumCols;i++) {
        for (var j = 0;j < NumRows;j++) {
            AllPosition[(i * NumCols) + j] = [i,j];
        }
    }
    Shuffle(AllPosition);
    for (i = 0;i < NumMines && AllPosition.length > 0;i++) {
        var NewMine = AllPosition.pop();
        Board[NewMine[0]][NewMine[1]] = MINE_ITEM;
    }
}
function InitializeMineCounts() {
    for (var r = 0;r < NumCols;r++) {
        for (var c = 0;c < NumRows;c++) {
            if (Board[r][c] != MINE_ITEM) {
                var Count = 0;
                for (var k = 0;k < Neighbors.length;k++) {
                    var NewR = r + Neighbors[k][0];
                    var NewC = c + Neighbors[k][1]
                    if (ValidPosition(NewR, NewC) && Board[NewR][NewC] == MINE_ITEM) {
                        Count++;
                    }
                }
                Board[r][c] = Numbers[Count];
            }
        }
    }
}
function InitializeBlankSpaces() {
    for (var i = 0;i < NumCols;i++) {
        for (var j = 0;j < NumRows;j++) {
            if (Board[i][j] == null) {
                Board[i][j] = HIDDEN_ITEM;
            }
        }
    }
}
function ConstructBoardString() {
    var ret = "Number of Empty Spaces Left: " + LeftToBeRevealed + "\r\n";
    var num = 0;
    for (var i = 0;i < NumCols;i++) {
        for (var j = 0;j < NumRows;j++) {
            if (Revealed[i][j] == VALUE_REVEALED) {
                ret += "#L"+num+"##v"+Board[i][j]+"##l";
            } else {
                if (DEBUG && Board[i][j] == MINE_ITEM) {
                    ret += "#L"+num+"##v"+MINE_ITEM+"##l";
                } else {
                    ret += "#L"+num+"##v"+HIDDEN_ITEM+"##l";
                }
            }
            num++;
        }
        ret += "\r\n";
    }
    return ret;
}
function ConstructEndBoardString() {
    var ret = "";
    var num = 0;
    for (var i = 0;i < NumCols;i++) {
        for (var j = 0;j < NumRows;j++) {
            if (Revealed[i][j] == VALUE_REVEALED) {
                if (Board[i][j] == MINE_ITEM) {
                    ret += "#v"+EXPLODED_ITEM+"#";
                } else {
                    ret += "#v"+Board[i][j]+"#";
                }
            } else {
                if (Board[i][j] == MINE_ITEM) {
                    ret += "#v"+MINE_ITEM+"#";
                } else {
                    ret += "#v"+HIDDEN_ITEM+"#";
                }
            }
            num++;
        }
        ret += "\r\n";
    }
    return ret;
}
function Shuffle(arr) {
    var i = arr.length;
    if (i == 0)
        return;
    while (--i) {
        var j = Math.floor( Math.random() * ( i + 1 ) );
        var tempi = arr[i];
        var tempj = arr[j];
        arr[i] = tempj;
        arr[j] = tempi;
    }
}
function ValidPosition(r, c) {
    return r >= 0 && r < NumRows && c >= 0 && c < NumCols;
}
function GetPositionFromSelection(sel) {
    return [(sel / NumCols) | 0, (sel % NumCols) | 0];
}
function IsGameOver() {
    return LeftToBeRevealed == 0;
}
function GetGameTime(End) {
    var Diff = End - StartTime;
    var MilliSec = (Diff % 1000) | 0;
    Diff /= 1000;
    var Min = (Diff / 60) | 0;
    var Sec = (Diff % 60) | 0;
    return ((Min < 10) ? "0" + Min : Min) + ":" + ((Sec < 10) ? "0" + Sec : Sec)
        + "." + ((MilliSec < 100) ? "0" + ((MilliSec < 10) ? "0" + MilliSec : MilliSec) : MilliSec);

}
function action(mode, type, selection) {
    if (mode == -1 || mode == 0)
        cm.dispose();
    else {
        if (status != 2)
            status++;

        if (status == 0) {
            cm.sendSimple(Header()+"Please select a mode:\r\n"+ConstructModeSelectionString())
        } else if (status == 1) {
            if (selection < 0 || selection > Modes.length) { //Packet Edits
                cm.dispose();
                return;
            }
            ModeSelected = selection;
            InitializeBoard();
            cm.sendSimple(Header() + ConstructBoardString());
        } else if (status == 2) {
            if (StartTime == -1) {
                StartTime = (new Date()).getTime();
            }
            var SendStr = Header();
            var Move = GetPositionFromSelection(selection);
            if (!ValidPosition(Move[0], Move[1])) {
                cm.sendOk("PE Detected ...");
                return;
            }
            if (Revealed[Move[0]][Move[1]] == VALUE_REVEALED) { //Already went there
                SendStr += "You have already moved in that space ...\r\n\r\n" + ConstructBoardString();
                cm.sendSimple(SendStr);
                return;
            }
            Revealed[Move[0]][Move[1]] = VALUE_REVEALED;
            LeftToBeRevealed--;
            SendStr += ConstructBoardString();
            if (Board[Move[0]][Move[1]] == MINE_ITEM) {
                //Lose
                cm.sendOk(Header() + ConstructEndBoardString() + "\r\nYou lost! Game Time: " + GetGameTime((new Date()).getTime()));
                cm.dispose();
            } else {
                if (IsGameOver()) {
                    cm.sendOk(Header() + ConstructEndBoardString() + "\r\nYou won! Game Time: " + GetGameTime((new Date()).getTime()));
                    cm.dispose();
                } else {
                    cm.sendSimple(SendStr);
                }
            }
        }
    }
}

For Mine densities closer to the Window's Minesweeper, use this Modes array (thanks Moogra):
Code:
var Modes = [
    ["#gEasy                 #k", 5, 5, 3],     //12% Density
    ["#bIntermediate   #k", 6, 6, 6],           //16% Density
    ["#rHard                 #k", 7, 7, 10]     //20% Density
];

Emilyx3 - [Add-On]Minesweeper NPC - RaGEZONE Forums


Enjoy ~ (May be buggy)
 
Last edited:
Just wow, I'm not impressed by the code as much as I'm impressing by your patience.
Try taking your skills to somewhere else and give this community something they wont belive that can be created I know you can, GL.
 
Just wow, I'm not impressed by the code as much as I'm impressing by your patience.
Try taking your skills to somewhere else and give this community something they wont belive that can be created I know you can, GL.
Translation please?

Anyways, good job! Never seen something like this before. Although you could have used your skills for something else though.
 
Back