hexagonal cipher(pipeline puzzle)
inspire by game : Warframe cipher
http://www.youtube.com/watch?v=UufvXoohs28
* minimalcomps old version has bug in Combobox... so i Changed stage select Component to NumericStepper.
** added Hint button
*** added Progress Label
/**
* Copyright greentec ( http://wonderfl.net/user/greentec )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/hTRQ
*/
package {
import com.bit101.components.Label;
import com.bit101.components.ComboBox;
import com.bit101.components.PushButton;
import com.bit101.components.NumericStepper;
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.geom.ColorTransform;
public class FlashTest extends Sprite {
public var _backBD:BitmapData;
public var _backB:Bitmap;
public var _width:int = 465;
public var _height:int = 465;
public var difficulty:int = 1;
public var difficultyMax:int = 10;
public var mapSerialArray:Vector.<Vector.<int>> = new Vector.<Vector.<int>>(); //for performance
public var neighbors:Array = [];
public var mapSize:int = 10;
public var map:Vector.<Vector.<Vector.<HexCell>>> = new Vector.<Vector.<Vector.<HexCell>>>(2 * mapSize + 1);
public var edgeLength:int = 13;
public var edgeW:int;
public var edgeH:int;
public var cellSprite:Sprite;
public var startButton:PushButton;
public var nextButton:PushButton;
public var hintButton:PushButton;
public var hintSprite:Sprite;
//public var stageComboBox:ComboBox;
public var stageComboBox:NumericStepper;
public var gameBoard:Array = [];
//public var stageArray:Array = [1, 2, 3, 4, 5, 6, 7, 8, 9];
public var isGameStarted:Boolean = false;
public var progressLabel:Label;
public var totalCellNum:int;
public var correctCellNum:int;
public var whiteColT:ColorTransform;
public function FlashTest() {
// write as3 code here..
_backBD = new BitmapData(_width, _height, false, 0x292929);
_backB = new Bitmap(_backBD);
addChild(_backB);
var i:int;
for (i = 0; i < 6; i += 1)
{
neighbors[i] = [];
}
neighbors[0] = [+1, -1, 0];
neighbors[1] = [+1, 0, -1];
neighbors[2] = [0, +1, -1];
neighbors[3] = [-1, +1, 0];
neighbors[4] = [-1, 0, +1];
neighbors[5] = [0, -1, +1];
edgeW = edgeLength * 3 / 2;
edgeH = edgeLength * Math.sqrt(3) / 2;
cellSprite = new Sprite();
addChild(cellSprite);
hintSprite = new Sprite();
hintSprite.mouseChildren = false;
hintSprite.mouseEnabled = false;
addChild(hintSprite);
initMap(map);
drawMap(map);
//stageComboBox = new ComboBox(this, _width - 110, 10, "", stageArray);
//stageComboBox.selectedIndex = 0;
stageComboBox = new NumericStepper(this, _width - 110, 10);
stageComboBox.minimum = 1;
stageComboBox.maximum = 9;
stageComboBox.step = 1;
stageComboBox.value = 1;
stageComboBox.width = 100;
startButton = new PushButton(this, stageComboBox.x, stageComboBox.y + stageComboBox.height + 5, "START GAME", onStartGame);
startButton.height *= 1.5;
hintButton = new PushButton(this, startButton.x + 50, startButton.y + startButton.height + 5, "HINT", onHint);
hintButton.height *= 1.5;
hintButton.width /= 2;
nextButton = new PushButton(this, _width / 2, _height / 2, "NEXT STAGE", onNextStage);
nextButton.width *= 2;
nextButton.height *= 2;
nextButton.x -= nextButton.width / 2;
nextButton.y -= nextButton.height / 2 + 150;
//nextButton.alpha = 0.7;
nextButton.visible = false;
progressLabel = new Label(this, 10, 10, "");
whiteColT = new ColorTransform(0, 0, 0, 1, 255, 255, 255, 0);
progressLabel.transform.colorTransform = whiteColT;
onStartGame();
}
private function onHint(e:Event):void
{
if (isGameStarted == true)
{
hintButton.enabled = false;
hintSprite.alpha = 1;
hintSprite.graphics.clear();
hintSprite.graphics.lineStyle(1, 0xff0000);
hintSprite.graphics.beginFill(0xff0000, 0.5);
var i:int, j:int;
var isValid:Boolean = true;
var binarySum:int;
for (i = 0; i < gameBoard.length; i += 1)
{
isValid = true;
if (gameBoard[i].rot != 0)
{
isValid = false;
}
binarySum = 0;
for (j = 0; j < gameBoard[i].lines.length; j += 1)
{
binarySum += Math.pow(2, j) * gameBoard[i].lines[j];
}
if (isValid == false)
{
if (binarySum == 63)//all line - 1,1,1,1,1,1
{
isValid = true;
}
else if (binarySum == 21 || binarySum == 42)// three lines - 1,0,1,0,1,0 or 0,1,0,1,0,1
{
if (gameBoard[i].rot % 2 == 0)
{
isValid = true;
}
}
else if (binarySum == 9 || binarySum == 18 || binarySum == 36)//two lines - 1,0,0,1,0,0 or 0,1,0,0,1,0 or 0,0,1,0,0,1
{
if (gameBoard[i].rot % 3 == 0)
{
isValid = true;
}
}
else if (binarySum == 27 || binarySum == 54 || binarySum == 45)// X-shape - 1,1,0,1,1,0 or 0,1,1,0,1,1 or 1,0,1,1,0,1
{
if (gameBoard[i].rot % 3 == 0)
{
isValid = true;
}
}
}
if (isValid == false)
{
hintSprite.graphics.drawCircle(gameBoard[i].x, gameBoard[i].y, edgeW / 2);
}
}
hintSprite.graphics.endFill();
addEventListener(Event.ENTER_FRAME, onHintShade);
}
}
private function onHintShade(e:Event):void
{
hintSprite.alpha -= 0.015;
if (hintSprite.alpha <= 0)
{
hintSprite.alpha = 0;
removeEventListener(Event.ENTER_FRAME, onHintShade);
}
}
private function printProgress():void
{
var i:int, j:int;
var binarySum:int;
correctCellNum = 0;
for (i = 0; i < gameBoard.length; i += 1)
{
if (gameBoard[i]._enable == true)
{
if (gameBoard[i].rot == 0)
{
correctCellNum += 1;
}
else
{
binarySum = 0;
for (j = 0; j < gameBoard[i].lines.length; j += 1)
{
binarySum += Math.pow(2, j) * gameBoard[i].lines[j];
}
if (binarySum == 63)//all line - 1,1,1,1,1,1
{
correctCellNum += 1;
}
else if (binarySum == 21 || binarySum == 42)// three lines - 1,0,1,0,1,0 or 0,1,0,1,0,1
{
if (gameBoard[i].rot % 2 == 0)
{
correctCellNum += 1;
}
}
else if (binarySum == 9 || binarySum == 18 || binarySum == 36)//two lines - 1,0,0,1,0,0 or 0,1,0,0,1,0 or 0,0,1,0,0,1
{
if (gameBoard[i].rot % 3 == 0)
{
correctCellNum += 1;
}
}
else if (binarySum == 27 || binarySum == 54 || binarySum == 45)// X-shape - 1,1,0,1,1,0 or 0,1,1,0,1,1 or 1,0,1,1,0,1
{
if (gameBoard[i].rot % 3 == 0)
{
correctCellNum += 1;
}
}
}
}
}
progressLabel.text = "Progress : " + String(int(correctCellNum / totalCellNum * 10000) / 100) + " %";
}
private function onHexCellClick(e:MouseEvent):void
{
var hexCell:HexCell = e.target as HexCell;
hexCell.rot += 1;
hexCell.rot %= 6;
hexCell.rotation += 60;
printProgress();
if (isGameStarted == true && checkAllCorrect(gameBoard) == true)
{
nextButton.visible = true;
if (cellSprite.hasEventListener(MouseEvent.CLICK) == true)
{
cellSprite.removeEventListener(MouseEvent.CLICK, onHexCellClick, true);
}
if (difficulty >= difficultyMax)
{
nextButton.label = "ALL CLEAR!!";
nextButton.enabled = false;
}
}
}
private function onNextStage(e:Event):void
{
nextButton.visible = false;
hintButton.enabled = true;
difficulty += 1;
//stageComboBox.selectedIndex += 1;
stageComboBox.value += 1;
makeGameBoard(difficulty);
progressLabel.text = "";
if (cellSprite.hasEventListener(MouseEvent.CLICK) == false)
{
cellSprite.addEventListener(MouseEvent.CLICK, onHexCellClick, true);
}
}
private function checkAllCorrect(arr:Array):Boolean
{
var i:int, j:int;
var isValid:Boolean = true;
var binarySum:int;
correctCellNum = 0;
for (i = 0; i < arr.length; i += 1)
{
if (arr[i].rot != 0)
{
isValid = false;
}
binarySum = 0;
for (j = 0; j < arr[i].lines.length; j += 1)
{
binarySum += Math.pow(2, j) * arr[i].lines[j];
}
//trace("B", binarySum);
if (isValid == false)
{
if (binarySum == 63)//all line - 1,1,1,1,1,1
{
isValid = true;
continue;
}
else if (binarySum == 21 || binarySum == 42)// three lines - 1,0,1,0,1,0 or 0,1,0,1,0,1
{
if (arr[i].rot % 2 == 0)
{
isValid = true;
continue;
}
else
{
return false;
}
}
else if (binarySum == 9 || binarySum == 18 || binarySum == 36)//two lines - 1,0,0,1,0,0 or 0,1,0,0,1,0 or 0,0,1,0,0,1
{
if (arr[i].rot % 3 == 0)
{
isValid = true;
continue;
}
else
{
return false;
}
}
else if (binarySum == 27 || binarySum == 54 || binarySum == 45)// X-shape - 1,1,0,1,1,0 or 0,1,1,0,1,1 or 1,0,1,1,0,1
{
if (arr[i].rot % 3 == 0)
{
isValid = true;
continue;
}
else
{
return false;
}
}
else
{
return false;
}
}
}
return true;
}
private function onStartGame(e:Event = null):void
{
isGameStarted = true;
nextButton.visible = false;
hintButton.enabled = true;
if(cellSprite.hasEventListener(MouseEvent.CLICK) == false)
{
cellSprite.addEventListener(MouseEvent.CLICK, onHexCellClick, true);
}
//difficulty = stageComboBox.selectedItem + 1;
difficulty = stageComboBox.value + 1;
makeGameBoard(difficulty);
progressLabel.text = "";
}
private function makeGameBoard(difficulty:int):void
{
var i:int, j:int, k:int;
var hexCell:HexCell;
var hexCell2:HexCell;
var dx:int, dy:int, dz:int;
var angle:Number;
var isValid:Boolean;
totalCellNum = 0;
gameBoard = [];
edgeLength = 13 + (10 - difficulty);
edgeW = edgeLength * 3 / 2;
edgeH = edgeLength * Math.sqrt(3) / 2;
for (i = 0; i < mapSerialArray.length; i += 1)
{
hexCell = map[mapSerialArray[i][0] + mapSize][mapSerialArray[i][1] + mapSize][mapSerialArray[i][2] + mapSize];
hexCell._enable = false;
hexCell._G.graphics.clear();
hexCell._GLine.graphics.clear();
}
for (i = -1 * difficulty; i < difficulty + 1; i += 1)
{
for (j = -1 * difficulty; j < difficulty + 1; j += 1)
{
for (k = -1 * difficulty; k < difficulty + 1; k += 1)
{
if (i + j + k == 0 && Math.random() < 0.7)
{
hexCell = map[mapSize + i][mapSize + j][mapSize + k];
hexCell.lines = [0, 0, 0, 0, 0, 0];
hexCell._enable = true;
hexCell.edgeLength = edgeLength;
hexCell.rot = 0;
hexCell.rotation = 0;
hexCell.drawCell(hexCell._G.graphics, Math.random() * 0xff << 8, true);
hexCell.drawCell(hexCell._GLine.graphics, 0xffffff, false);
hexCell.x = _width / 2 + hexCell._x * edgeW;
hexCell.y = _height / 2 + (0 - hexCell._y + hexCell._z) * edgeH;
gameBoard.push(hexCell);
}
}
}
}
for (i = 0; i < gameBoard.length; i += 1)
{
hexCell = gameBoard[i];
for (j = 0; j < 6; j += 1) //make Lines
{
if (hexCell.lines[j] == 0)
{
dx = neighbors[j][0] + hexCell._x;
dy = neighbors[j][1] + hexCell._y;
dz = neighbors[j][2] + hexCell._z;
if (dx <= mapSize && dx >= -mapSize &&
dy <= mapSize && dy >= -mapSize &&
dz <= mapSize && dz >= -mapSize)
{
if (map[mapSize + dx][mapSize + dy][mapSize + dz] != null &&
map[mapSize + dx][mapSize + dy][mapSize + dz]._enable == true)
{
hexCell2 = map[mapSize + dx][mapSize + dy][mapSize + dz];
if (Math.random() < 0.5)
{
hexCell.lines[j] = 1;
if (j < 3)
{
hexCell2.lines[j + 3] = 1;
}
else
{
hexCell2.lines[j - 3] = 1;
}
}
}
}
}
}
}
for (i = 0; i < gameBoard.length; i += 1)
{
hexCell = gameBoard[i];
isValid = false;
for (j = 0; j < 6; j += 1) //draw Lines
{
if (hexCell.lines[j] == 1)
{
isValid = true;
angle = -1 * 2 * Math.PI / 6 * (j - 0.5); //counter clock-wise(-1)
hexCell._G.graphics.lineStyle(1, 0xffffff);
hexCell._G.graphics.moveTo(0, 0);
hexCell._G.graphics.lineTo(Math.cos(angle) * edgeW / 2, Math.sin(angle) * edgeW / 2);
}
}
if (isValid == true)
{
hexCell.rot = Math.random() * 6;
hexCell.rotation = hexCell.rot * 60;
totalCellNum += 1;
}
else //empty cell will not show
{
hexCell._G.graphics.clear();
hexCell._GLine.graphics.clear();
hexCell._enable = false;
}
}
}
private function onHexCellMouseOver(e:MouseEvent):void
{
var hexCell:HexCell = e.target as HexCell;
hexCell.alpha = 0.5;
}
private function onHexCellMouseOut(e:MouseEvent):void
{
var hexCell:HexCell = e.target as HexCell;
hexCell.alpha = 1;
}
private function drawMap(map:Vector.<Vector.<Vector.<HexCell>>>):void
{
var i:int;
var hexCell:HexCell;
for (i = 0; i < mapSerialArray.length; i += 1)
{
hexCell = map[mapSerialArray[i][0] + mapSize][mapSerialArray[i][1] + mapSize][mapSerialArray[i][2] + mapSize];
//hexCell.drawCell(hexCell._G.graphics, Math.random() * 0xff << 8, true);
//hexCell.drawCell(hexCell._GLine.graphics, 0xffffff, false);
hexCell.x = _width / 2 + hexCell._x * edgeW;
hexCell.y = _height / 2 + (0 - hexCell._y + hexCell._z) * edgeH;
}
cellSprite.addEventListener(MouseEvent.CLICK, onHexCellClick, true);
cellSprite.addEventListener(MouseEvent.MOUSE_OVER, onHexCellMouseOver, true);
cellSprite.addEventListener(MouseEvent.MOUSE_OUT, onHexCellMouseOut, true);
}
private function initMap(map:Vector.<Vector.<Vector.<HexCell>>>):void
{
var i:int, j:int, k:int;
var hexCell:HexCell;
var serialIndex:int = 0;
for (i = -1 * mapSize; i < mapSize + 1; i += 1)
{
map[i+mapSize] = new Vector.<Vector.<HexCell>>(2 * mapSize + 1);
for (j = -1 * mapSize; j < mapSize + 1; j += 1)
{
map[i+mapSize][j+mapSize] = new Vector.<HexCell>(2 * mapSize + 1);
for (k = -1 * mapSize; k < mapSize + 1; k += 1)
{
if (i + j + k == 0)
{
hexCell = new HexCell(i, j, k, edgeLength);
cellSprite.addChild(hexCell);
map[i + mapSize][j + mapSize][k + mapSize] = hexCell;
mapSerialArray[serialIndex] = new Vector.<int>(3);
mapSerialArray[serialIndex][0] = i;
mapSerialArray[serialIndex][1] = j;
mapSerialArray[serialIndex][2] = k;
serialIndex += 1;
}
}
}
}
}
}
}
Class
{
import flash.display.Shape;
import flash.display.Sprite;
import flash.display.Graphics;
/**
* ...
* @author ypc
*/
class HexCell extends Sprite
{
public var _x:int;
public var _y:int;
public var _z:int;
public var edgeLength:int;
public var _G:Shape;
public var _GLine:Shape;
public var lines:Array = [0, 0, 0, 0, 0, 0];
public var rot:int;
public var _enable:Boolean = false;
public function HexCell(_x:int, _y:int, _z:int, edgeLength:int)
{
this._x = _x;
this._y = _y;
this._z = _z;
this.edgeLength = edgeLength;
_G = new Shape();
addChild(_G);
_GLine = new Shape();
addChild(_GLine);
}
public function drawCell(_G:Graphics, color:uint = 0xcccccc, fill:Boolean = false):void
{
_G.clear();
if (fill == true)
{
_G.beginFill(color);
}
else
{
_G.lineStyle(1, color);
}
_G.moveTo(edgeLength, 0);
var i:int;
var angle:Number;
for (i = 1; i <= 6; i += 1)
{
angle = 2 * Math.PI / 6 * i;
_G.lineTo(edgeLength * Math.cos(angle), edgeLength * Math.sin(angle));
}
_G.endFill();
}
}
}