In case Flash no longer exists; a copy of this site is included in the Flashpoint archive's "ultimate" collection.

Dead Code Preservation :: Archived AS3 works from wonderfl.net

forked from: minesweeper

Get Adobe Flash player
by wh0 15 Apr 2010
    Embed
// forked from wh0's minesweeper
package {
	import net.user1.reactor.*;
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.Sprite;
	import flash.events.KeyboardEvent;
	import flash.events.MouseEvent;
	import flash.geom.Matrix;
	import flash.geom.Point;
	import flash.geom.Rectangle;
	import flash.text.TextField;
	import flash.text.TextFormat;
	import flash.ui.Keyboard;
	import flash.text.TextFormatAlign;
	public class Minesweeper extends Sprite {
		
		private static const WIDTH:int = 30;
		private static const HEIGHT:int = 16;
		private static const NUM_MINES:int = 99;
		private static const SIZE:int = 15;
		private static const DX:int = 8;
		private static const DY:int = 42;
		private static const LEFT:int = 90; // Z
		private static const RIGHT:int = 88; // X
		
		private static const MINES_AROUND:int = 0xf;
		private static const MARKS_AROUND:int = 0xf0;
		private static const MINE:int = 0x100;
		private static const OPEN:int = 0x200;
		private static const MARK:int = 0x400;
		
		private const FIELD:Vector.<Vector.<int>> = new Vector.<Vector.<int>>(HEIGHT, true);
		private const BITMAP:BitmapData = new BitmapData(WIDTH * SIZE, HEIGHT * SIZE, false);
		private const GRAPHICS:BitmapData = new BitmapData(180, 15, false);
		private const DEBUG:TextField = new TextField();
		private const REACTOR:Reactor = new Reactor();
		private var ROOM:Room;
		
		private var row:int = -1;
		private var col:int = -1;
		private var left:Boolean = false;
		private var right:Boolean = false;
		private var game:int = 0;
		private var score:int = 0;
		
		public function Minesweeper() {
			prepareGraphics();
			for (var r:int = 0; r < HEIGHT; r++)
				FIELD[r] = new Vector.<int>(WIDTH, true);
			var b:Bitmap = new Bitmap(BITMAP);
			b.x = DX;
			b.y = DY;
			addChild(b);
			DEBUG.width = 339;
			DEBUG.height = 144;
			DEBUG.x = 126;
			DEBUG.y = 321;
			addChild(DEBUG);
			REACTOR.addEventListener(ReactorEvent.READY, ready);
			REACTOR.connect('tryunion.com', 80);
		}
		
		private function prepareGraphics():void {
			var t:TextField = new TextField(); addChild(t); t.x = 1; t.y = -1; t.width = 14;
			t.defaultTextFormat = new TextFormat('Arial', 11, null, true, null, null, null, null, TextFormatAlign.CENTER);
			var m:Matrix = new Matrix();
			graphics.beginFill(0xc0c0c0); graphics.drawRect(0, 0, 15, 15); graphics.endFill();
			graphics.lineStyle(1, 0x808080); graphics.moveTo(15, 0); graphics.lineTo(0, 0); graphics.lineTo(0, 15);
			GRAPHICS.draw(this, m);
			t.textColor = 0x0000ff; t.text = '1'; m.translate(15, 0); GRAPHICS.draw(this, m);
			t.textColor = 0x008000; t.text = '2'; m.translate(15, 0); GRAPHICS.draw(this, m);
			t.textColor = 0xff0000; t.text = '3'; m.translate(15, 0); GRAPHICS.draw(this, m);
			t.textColor = 0x000080; t.text = '4'; m.translate(15, 0); GRAPHICS.draw(this, m);
			t.textColor = 0x800000; t.text = '5'; m.translate(15, 0); GRAPHICS.draw(this, m);
			t.textColor = 0x008080; t.text = '6'; m.translate(15, 0); GRAPHICS.draw(this, m);
			t.textColor = 0x808080; t.text = '7'; m.translate(15, 0); GRAPHICS.draw(this, m);
			t.textColor = 0x000000; t.text = '8'; m.translate(15, 0); GRAPHICS.draw(this, m);
			removeChild(t); graphics.clear();
			graphics.beginFill(0xc0c0c0); graphics.drawRect(0, 0, 15, 15); graphics.endFill();
			graphics.lineStyle(1, 0xffffff); graphics.moveTo(0, 14); graphics.lineTo(0, 0); graphics.lineTo(14, 0);
			graphics.moveTo(1, 13); graphics.lineTo(1, 1); graphics.lineTo(13, 1);
			graphics.lineStyle(1, 0x808080); graphics.moveTo(1, 14); graphics.lineTo(14, 14); graphics.lineTo(14, 1);
			graphics.moveTo(2, 13); graphics.lineTo(13, 13); graphics.lineTo(13, 2);
			m.translate(15, 0); GRAPHICS.draw(this, m);
			graphics.lineStyle(); graphics.beginFill(0xff0000); graphics.moveTo(9, 3); graphics.lineTo(4, 5); graphics.lineTo(9, 8); graphics.endFill();
			graphics.beginFill(0x000000); graphics.moveTo(9, 9); graphics.lineTo(11, 12); graphics.lineTo(4, 12); graphics.endFill();
			m.translate(15, 0); GRAPHICS.draw(this, m);
			graphics.clear();
			graphics.beginFill(0xff0000); graphics.drawRect(0, 0, 15, 15); graphics.endFill();
			graphics.lineStyle(1, 0x808080); graphics.moveTo(15, 0); graphics.lineTo(0, 0); graphics.lineTo(0, 15);
			graphics.lineStyle(); graphics.beginFill(0x000000); graphics.drawCircle(8, 8, 4); graphics.endFill();
			m.translate(15, 0); GRAPHICS.draw(this, m);
			graphics.clear();
		}
		
		private function ready(e:ReactorEvent):void {
			DEBUG.appendText('connected\n');
			REACTOR.self().setAttribute('iconURL', loaderInfo.parameters['viewer.iconURL']);
			REACTOR.self().setAttribute('displayName', loaderInfo.parameters['viewer.displayName']);
			REACTOR.self().setAttribute('s', '0');
			ROOM = REACTOR.getRoomManager().createRoom('ms');
			ROOM.addEventListener(RoomEvent.JOIN, joinRoom);
			ROOM.join();
		}
		
		private function joinRoom(e:RoomEvent):void {
			DEBUG.appendText('joined\n');
			var a:Object = ROOM.getAttributes();
			var i:int;
			if (a.g) {
				loadGame(a.g.split(','));
				for (var n:String in a) {
					if (n.charAt(0) == 'o' && parseInt(a[n], 10) == game) {
						i = parseInt(n.substr(1), 10);
						var c:int = i % WIDTH;
						var r:int = i / WIDTH;
						simpleOpen(r, c);
					}
				}
			} else {
				createGame();
			}
			var o:Array = ROOM.getOccupants();
			for (i = 0; i < o.length; i++)
				addChild(new ClientDisplay(o[i]));
			ROOM.addEventListener(AttributeEvent.UPDATE, attrUpdate);
			ROOM.addEventListener(RoomEvent.ADD_OCCUPANT, addOcc);
			ROOM.addEventListener(RoomEvent.REMOVE_OCCUPANT, removeOcc);
			ROOM.addEventListener(RoomEvent.UPDATE_CLIENT_ATTRIBUTE, updateClientAttr);
			stage.addEventListener(MouseEvent.MOUSE_MOVE, mouse);
			stage.addEventListener(KeyboardEvent.KEY_DOWN, keydown);
			stage.addEventListener(KeyboardEvent.KEY_UP, keyup);
		}
		
		private function clear():void {
			for (var r:int = 0; r < HEIGHT; r++) {
				for (var c:int = 0; c < WIDTH; c++) {
					FIELD[r][c] = 0;
					cell(r, c, 9);
				}
			}
		}
		
		private function loadGame(a:Array):void {
			var i:int = parseInt(a[0], 10);
			if (i <= game)
				return;
			game = i;
			DEBUG.appendText('loading game ' + game + '\n');
			clear();
			for (var r:int = 0; r < HEIGHT; r++) {
				i = parseInt(a[r + 1], 10);
				for (var c:int = WIDTH - 1; c >= 0; c--) {
					if (i & 1) {
						FIELD[r][c] |= MINE;
						propagate(incMines, r, c);
					}
					i >>= 1;
				}
			}
			score = 0;
			REACTOR.self().setAttribute('s', '0');
		}
		
		private function createGame():void {
			DEBUG.appendText('creating game ' + (++game).toString() + '\n');
			clear();
			var i:int = 0;
			while (i < NUM_MINES) {
				var r:int = Math.random() * HEIGHT;
				var c:int = Math.random() * WIDTH;
				if (FIELD[r][c] & MINE)
					continue;
				FIELD[r][c] |= MINE;
				i++;
				propagate(incMines, r, c);
			}
			sendGame();
			score = 0;
			REACTOR.self().setAttribute('s', '0');
		}
		
		private function sendGame():void {
			var a:String = game.toString();
			for (var r:int = 0; r < HEIGHT; r++) {
				var i:int = 0;
				for (var c:int = 0; c < WIDTH; c++)
					i = i << 1 | (FIELD[r][c] & MINE) >> 8;
				a += ',' + i.toString();
			}
			ROOM.setAttribute('g', a);
		}
		
		private function attrUpdate(e:AttributeEvent):void {
			var a:Attribute = e.getChangedAttr();
			var r:int, c:int, i:int;
			if (a.name.charAt(0) == 'o' && parseInt(a.value, 10) == game) {
				i = parseInt(a.name.substr(1), 10);
				c = i % WIDTH;
				r = i / WIDTH;
				simpleOpen(r, c);
			} else if (a.name == 'g') {
				loadGame(a.value.split(','));
			}
		}
		
		private function addOcc(e:RoomEvent):void {
			var a:IClient = e.getClient();
			addChild(new ClientDisplay(a));
		}
		
		private function removeOcc(e:RoomEvent):void {
			ClientDisplay.remove(e.getClient().getClientID());
		}
		
		private function updateClientAttr(e:RoomEvent):void {
			var a:Attribute = e.getChangedAttr();
			if (a.name == 's')
				ClientDisplay.setScore(e.getClient().getClientID(), a.value);
		}
		
		private function sendOpen(r:int, c:int):void {
			ROOM.setAttribute('o' + (r * WIDTH + c), game.toString());
			REACTOR.self().setAttribute('s', score.toString());
		}
		
		private function simpleOpen(r:int, c:int):void {
			if (!bound(r, c))
				return;
			if (FIELD[r][c] & OPEN)
				return;
			FIELD[r][c] |= OPEN;
			if (FIELD[r][c] & MINE) {
				cell(r, c, 11);
				propagate(incMarks, r, c);
			} else {
				cell(r, c, FIELD[r][c] & MINES_AROUND);
			}
		}
		
		private function mouse(e:MouseEvent):void {
			if (left) {
				release(row, col);
				if (right)
					propagate(release, row, col);
			}
			row = (e.stageY - DY) / SIZE;
			col = (e.stageX - DX) / SIZE;
			if (left) {
				depress(row, col);
				if (right)
					propagate(depress, row, col);
			}
		}
		
		private function keydown(e:KeyboardEvent):void {
			if (e.keyCode == LEFT) {
				left = true;
				depress(row, col);
				if (right)
					propagate(depress, row, col);
			} else if (e.keyCode == RIGHT) {
				if (!right) {
					right = true;
					if (left) {
						depress(row, col);
						propagate(depress, row, col);
					} else {
						mark(row, col);
					}
				}
			} else if (e.keyCode == Keyboard.F2) {
				if (!left)
					createGame();
			}
		}
		
		private function keyup(e:KeyboardEvent):void {
			if (e.keyCode == LEFT) {
				if (left) {
					left = false;
					release(row, col);
					if (right) {
						propagate(release, row, col);
						special(row, col);
					} else {
						open(row, col);
					}
				}
			} else if (e.keyCode == RIGHT) {
				right = false;
				if (left) {
					left = false;
					release(row, col);
					propagate(release, row, col);
					special(row, col);
				}
			}
		}
		
		private function depress(r:int, c:int):void {
			if (!bound(r, c))
				return;
			if (FIELD[r][c] & (OPEN | MARK))
				return;
			cell(r, c, 0);
		}
		
		private function release(r:int, c:int):void {
			if (!bound(r, c))
				return;
			if (FIELD[r][c] & (OPEN | MARK))
				return;
			cell(r, c, 9);
		}
		
		private function open(r:int, c:int):void {
			if (!bound(r, c))
				return;
			if (FIELD[r][c] & (OPEN | MARK))
				return;
			FIELD[r][c] |= OPEN;
			if (FIELD[r][c] & MINE) {
				cell(r, c, 11);
				score -= 30;
				propagate(incMarks, r, c);
				sendOpen(r, c);
			} else {
				cell(r, c, FIELD[r][c] & MINES_AROUND);
				score++;
				sendOpen(r, c);
				if ((FIELD[r][c] & MINES_AROUND) == 0)
					propagate(open, r, c);
			}
		}
		
		private function mark(r:int, c:int):void {
			if (!bound(r, c))
				return;
			if (FIELD[r][c] & OPEN)
				return;
			if (FIELD[r][c] & MARK) {
				cell(r, c, 9);
				FIELD[r][c] &= ~MARK;
				propagate(decMarks, r, c);
			} else {
				cell(r, c, 10);
				FIELD[r][c] |= MARK;
				propagate(incMarks, r, c);
			}
		}
		
		private function special(r:int, c:int):void {
			if (!bound(r, c))
				return;
			if (!(FIELD[r][c] & OPEN))
				return;
			if ((FIELD[r][c] & MINES_AROUND) != (FIELD[r][c] & MARKS_AROUND) >> 4)
				return;
			propagate(open, r, c);
		}
		
		private function incMines(r:int, c:int):void {
			if (!bound(r, c))
				return;
			FIELD[r][c] += 0x1;
		}
		
		private function incMarks(r:int, c:int):void {
			if (!bound(r, c))
				return;
			FIELD[r][c] += 0x10;
		}
		
		private function decMarks(r:int, c:int):void {
			if (!bound(r, c))
				return;
			FIELD[r][c] -= 0x10;
		}
		
		private function propagate(a:Function, r:int, c:int):void {
			a(r - 1, c - 1);
			a(r - 1, c    );
			a(r - 1, c + 1);
			a(r    , c - 1);
			a(r    , c + 1);
			a(r + 1, c - 1);
			a(r + 1, c    );
			a(r + 1, c + 1);
		}
		
		private function bound(r:int, c:int):Boolean {
			return r >= 0 && r < HEIGHT && c >= 0 && c < WIDTH;
		}
		
		private function cell(r:int, c:int, i:int):void {
			BITMAP.copyPixels(GRAPHICS, new Rectangle(i * SIZE, 0, SIZE, SIZE), new Point(c * SIZE, r * SIZE));
		}
		
	}
}

import net.user1.reactor.*;
import flash.display.Sprite;
import flash.display.Loader;
import flash.net.URLRequest;
import flash.text.TextField;
import flash.text.TextFormat;
import flash.text.TextFormatAlign;
import flash.events.Event;
class ClientDisplay extends Sprite {
	
	private static const instances:Object = new Object();
	private static var tail:ClientDisplay;
	private static var count:int = 0;
	
	private var icon:Loader;
	private var nameField:TextField;
	private var scoreField:TextField;
	private var prev:ClientDisplay;
	private var next:ClientDisplay;
	
	public function ClientDisplay(client:IClient) {
		instances[client.getClientID()] = this;
		prev = tail;
		if (tail)
			tail.next = this;
		tail = this;
		
		icon = new Loader();
		icon.load(new URLRequest(client.getAttribute('iconURL')));
		addChild(icon);
		
		var f:TextFormat = new TextFormat();
		f.align = TextFormatAlign.CENTER;
		
		nameField = new TextField();
		nameField.defaultTextFormat = f;
		nameField.width = 100;
		nameField.height = 16;
		nameField.y = 104;
		nameField.text = client.getAttribute('displayName');
		addChild(nameField);
		
		scoreField = new TextField();
		scoreField.defaultTextFormat = f;
		scoreField.width = 100;
		scoreField.height = 16;
		scoreField.y = 124;
		scoreField.text = client.getAttribute('s');
		addChild(scoreField);
		
		x = count++ * 113 + 13;
		y = 321;
	}
	
	public static function remove(id:String):void {
		var o:ClientDisplay = instances[id];
		if (o == null)
			return;
		if (o.prev)
			o.prev.next = o.next;
		if (o.next)
			o.next.prev = o.prev;
		if (tail == o)
			tail = o.prev;
		o.parent.removeChild(o);
		for (o = o.next; o; o = o.next) {
			o.x -= 113;
		}
		count--;
	}
	
	public static function setScore(id:String, score:String):void {
		var o:ClientDisplay = instances[id];
		if (o == null)
			return;
		o.scoreField.text = score;
	}
	
}