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

マモノ・スイーパーをズルしてみた

もう手でやるのめんどくさいからAIにやらせるよ!
HP:1ではじめてるから、すぐ死んだらreloadしてね!
@see http://www.hojamaka.com/game/mamono_sweeper/
Get Adobe Flash player
by uwi 08 Jun 2010
// もう手でやるのめんどくさいからAIにやらせるよ!
// HP:1ではじめてるから、すぐ死んだらreloadしてね!
// @see http://www.hojamaka.com/game/mamono_sweeper/
package {
	import flash.display.Sprite;
	import flash.text.TextField;
	import flash.events.*;

	[SWF(frameRate=10)] 
	public class MSSolver extends Sprite {
	private var _tf : TextField;
	private var _q : Array; // ぽちらなければいけないセル
	private var _mm : MS;
	private var _logic : MSLogic;

	public function MSSolver() {
		_tf = new TextField();
		_tf.width = 100;
		_tf.height = 100;
		addChild(_tf);

		// enemy : Object = {level, hp, attack, exp, count}
		_logic = new MSLogic(30, 16, [
			{level:1, hp:1, attack:1, exp:1, count:33},
			{level:2, hp:2, attack:2, exp:2, count:27},
			{level:3, hp:3, attack:3, exp:4, count:20},
			{level:4, hp:4, attack:4, exp:8, count:13},
			{level:5, hp:5, attack:5, exp:16, count:6}
			], 1, [10, 50, 167, 271]);
		_mm = new MS(_logic);

		addChild(_mm);
		_mm.x = stage.stageWidth / 2;
		_mm.y = stage.stageHeight / 2;

		_q = [];
		addEventListener(Event.ENTER_FRAME, onEnterFrame);
	}

	private function onEnterFrame(e : Event) : void
	{
		step();
	}

	private function step() : void
	{
		var w : uint = _logic.w;
		var h : uint = _logic.h;
		var r : uint, c : uint;
		_tf.text = "hp : " + _logic.hp + "\nlevel : " + _logic.level + "\nexp : " + _logic.exp;

		// キューがあればひっくり返す
		var prevlv : uint = _logic.level;
		while(_q.length > 0){
		var pos : Object = _q.pop();
		if(_logic.hp > pos.damage && _logic.flip(pos.r, pos.c)){
		break;
		}
		}

		// しんじゃった
		if(_logic.hp <= 0){
			tr("\ndead end");
			removeEventListener(Event.ENTER_FRAME, onEnterFrame);
		}
		// レベルアップ、またはキューがないときmarkmapをチェック
		if(_q.length == 0 || prevlv < _logic.level){
			for(r = 0; r < h;r++){
				for(c = 0;c < w;c++){
					if(_logic.flipped[r][c] == 0 && _mm.markmap[r][c] > 0){
						for each(e in _logic.enemies){
							if(e.level == _mm.markmap[r][c]){
								// 仮想戦闘
								ret = MSLogic.combat(_logic.hp, _logic.level, e.hp, e.attack);
								if(ret > 0){
									// 勝ったら開きに行く
									_q.push({r:r, c:c, damage:_logic.hp - ret});
								}
								break;
							}
						}
					}
				}
			}
		}

		if(_q.length == 0){
			for(r = 0;r < h;r++){
				for(c = 0;c < w;c++){
					if(_logic.flipped[r][c] == 0)continue;
					if((_logic.map[r][c] & 0xff) == 0)continue;
					if(_mm.markmap[r][c] == 999)continue;

					var cir : uint = 0;
					var cirsum : uint = 0;
					var unflipped : Array = [];
					for(var dr : int = -1;dr <= 1;dr++){
						for(var dc : int = -1;dc <= 1;dc++){
							if((dr != 0 || dc != 0) && _logic.isValid(r+dr, c+dc)){
								if(_logic.flipped[r+dr][c+dc] == 0){
									if(_mm.markmap[r+dr][c+dc] == 0){
										cir++;
										unflipped.push({r:r+dr, c:c+dc, damage:0});
									}else{
										cirsum += _mm.markmap[r+dr][c+dc];
									}
								}else{
									cirsum += _logic.map[r+dr][c+dc] >> 8;
								}
							}
						}
					}

					if(cir >= 1){
						var sub : int = (_logic.map[r][c] & 0xff) - cirsum;
						if(sub > 0){
							// 想定される敵を見つけて
							for each(var e : Object in _logic.enemies){
								if(e.level == sub){
									// 仮想戦闘
									var ret : int = MSLogic.combat(_logic.hp, _logic.level, e.hp, e.attack);
									if(ret > 0){
										// 勝ったら開きに行く
										for each(var u : Object in unflipped){
											u.damage = _logic.hp - ret;
											_q.push(u);
										}
									}else{
										// 負けたらマークするだけ
										if(cir == 1){
											u = unflipped[0];
											_mm.markmap[u.r][u.c] = sub;
										}
									}
									break;
								}
							}
						}else{
							// 敵が存在しないので無条件で開く
							_q = _q.concat(unflipped);
						}
					}else{
						_mm.markmap[r][c] = 999;
					}
				}
			}
		}

		// 走査してもキューが生成されなかった場合は適当にひっくり返す
		if(_q.length == 0){
			var seed : Array = [];
			for(r = 0;r < h;r++){
				for(c = 0;c < w;c++){
					if(_logic.flipped[r][c] == 0 && _mm.markmap[r][c] == 0){
						seed.push({r:r, c:c});
					}
				}
			}
			if(seed.length != 0){
				var candi : Object = seed[int(Math.random() * seed.length)];
				candi.damage = 0;
				_q.push(candi);
			}else{
				// 終了
				tr("\nend");
				removeEventListener(Event.ENTER_FRAME, onEnterFrame);
			}
		}

		_mm.paint();
	}

		private function tr(...o : Array) : void
		{
			_tf.appendText(o + "\n");
		}
	}
}

import flash.display.*;
import flash.geom.*;
import flash.text.*;

class MS extends Sprite
{
	private var _logic : MSLogic;
	
	private var _canvas : BitmapData;
	private const SIZE_CELL : uint = 14;
	private var _numberChips : Array;
	private var _markNumberChips : Array;
	private var _enemyChips : Array;
	private var _unflippedChip : BitmapData;
	
	private var _markmap : Vector.<Vector.<uint>>;
	private var _h : uint;
	private var _w : uint;
	private const COLOR_BG : uint = 0xeeeeee;
	private const COLOR_LINE : uint = 0x0;
	
	public function get markmap() : Vector.<Vector.<uint>> { return _markmap; }
	
	public function MS(logic : MSLogic)
	{
		_logic = logic;
		_w = logic.w;
		_h = logic.h;
		
		_numberChips = [];
		var tfmt : TextFormat = new TextFormat("arial", 10, 0x0);
		var bmd : BitmapData;
		var i : uint, j : uint;
		for(i = 0;i <= 50;i++){
			bmd = new BitmapData(SIZE_CELL, SIZE_CELL, false, COLOR_BG);
			if(i >= 1){
				var bmdt : BitmapData = textToBitmapData(i.toString(), tfmt);
				bmd.copyPixels(bmdt, bmdt.rect, new Point((bmd.width - bmdt.width) / 2, (bmd.height - bmdt.height) / 2));
			}
			bmd.fillRect(new Rectangle(0, 0, SIZE_CELL, 1), COLOR_LINE);
			bmd.fillRect(new Rectangle(0, 0, 1, SIZE_CELL), COLOR_LINE);
			bmd.fillRect(new Rectangle(0, SIZE_CELL-1, SIZE_CELL, 1), COLOR_LINE);
			bmd.fillRect(new Rectangle(SIZE_CELL-1, 0, 1, SIZE_CELL), COLOR_LINE);
			_numberChips.push(bmd);
		}
		
		_markNumberChips = [];
		var tfmtMark : TextFormat = new TextFormat("arial", 10, 0x00dd00);
		for(i = 0;i <= 50;i++){
			bmd = new BitmapData(SIZE_CELL, SIZE_CELL, false, 0x444444);
			if(i >= 1){
				bmdt = textToBitmapData(i.toString(), tfmtMark);
				bmd.copyPixels(bmdt, bmdt.rect, new Point((bmd.width - bmdt.width) / 2, (bmd.height - bmdt.height) / 2));
			}
			bmd.fillRect(new Rectangle(0, 0, SIZE_CELL, 1), COLOR_LINE);
			bmd.fillRect(new Rectangle(0, 0, 1, SIZE_CELL), COLOR_LINE);
			bmd.fillRect(new Rectangle(0, SIZE_CELL-1, SIZE_CELL, 1), COLOR_LINE);
			bmd.fillRect(new Rectangle(SIZE_CELL-1, 0, 1, SIZE_CELL), COLOR_LINE);
			_markNumberChips.push(bmd);
		}
		
		_enemyChips = [null];
		for each(var c : uint in [0x00ffff, 0xff0000, 0xff00ff, 0xffff00, 0x00ff00]){
			bmd = new BitmapData(SIZE_CELL, SIZE_CELL, false, COLOR_BG);
			bmd.fillRect(bmd.rect, c);
			bmd.fillRect(new Rectangle(0, 0, SIZE_CELL, 1), COLOR_LINE);
			bmd.fillRect(new Rectangle(0, 0, 1, SIZE_CELL), COLOR_LINE);
			bmd.fillRect(new Rectangle(0, SIZE_CELL-1, SIZE_CELL, 1), COLOR_LINE);
			bmd.fillRect(new Rectangle(SIZE_CELL-1, 0, 1, SIZE_CELL), COLOR_LINE);
			_enemyChips.push(bmd);
		}
		
		_unflippedChip = new BitmapData(SIZE_CELL, SIZE_CELL, false, 0x444444);
		_unflippedChip.fillRect(new Rectangle(0, 0, SIZE_CELL, 1), COLOR_LINE);
		_unflippedChip.fillRect(new Rectangle(0, 0, 1, SIZE_CELL), COLOR_LINE);
		_unflippedChip.fillRect(new Rectangle(0, SIZE_CELL-1, SIZE_CELL, 1), COLOR_LINE);
		_unflippedChip.fillRect(new Rectangle(SIZE_CELL-1, 0, 1, SIZE_CELL), COLOR_LINE);
		
		_markmap = new Vector.<Vector.<uint>>(_h);
		for(i = 0;i < _h;i++){
			_markmap[i] = new Vector.<uint>(_w);
			for(j = 0;j < _w;j++){
				_markmap[i][j] = 0;
			}
		}
		
		_canvas = new BitmapData(SIZE_CELL * _w, SIZE_CELL * _h);
		var bmp : Bitmap = new Bitmap(_canvas);
		bmp.x = -SIZE_CELL * _w / 2;
		bmp.y = -SIZE_CELL * _h / 2;
		addChild(bmp);
		
		paint();
	}
	
	public function paint() : void
	{
		_canvas.lock();
		for(var i : uint = 0;i < _h;i++){
			for(var j : uint = 0;j < _w;j++){
				var chip : BitmapData;
				if(_logic.flipped[i][j] == 0){
					if(_markmap[i][j] > 0){
						chip = _markNumberChips[_markmap[i][j]];
					}else{
						chip = _unflippedChip;
					}
				}else if((_logic.map[i][j] >> 8) > 0){
					chip = _enemyChips[_logic.map[i][j] >> 8];
				}else{
					chip = _numberChips[_logic.map[i][j] & 0xf];
				}
				
				_canvas.copyPixels(chip, chip.rect, new Point(SIZE_CELL * j, SIZE_CELL * i));
			}
		}
		_canvas.unlock();
	}
	
	private function textToBitmapData(text : String, tfmt : TextFormat = null) : BitmapData
	{
		var tf : TextField = new TextField();
		tf.autoSize = "left";
		tf.textColor = COLOR_LINE;
		if(tfmt != null)tf.defaultTextFormat = tfmt;
		tf.text = text;
		
		var bmd : BitmapData = new BitmapData(tf.width, tf.height, true, COLOR_BG);
		bmd.draw(tf);
		return bmd;
	}
}

class MSLogic
{
	private var _w : uint;
	private var _h : uint;
	// lower 8bit : sum of neighbor levels
	// upper 8bit : index of enemies
	private var _map : Vector.<Vector.<uint>>;
	private var _flipped : Vector.<Vector.<uint>>;
	private var _enemies : Array;
	private var _hp : int;
	private var _exp : uint;
	private var _level : uint;
	private var _lvs : Array;
	
	public function get w() : uint { return _w; }
	public function get h() : uint { return _h; }
	public function get map() : Vector.<Vector.<uint>> { return _map; }
	public function get flipped() : Vector.<Vector.<uint>> { return _flipped; }
	public function get enemies() : Array { return _enemies; }
	public function get hp() : int { return _hp; }
	public function get exp() : int { return _exp; }
	public function get level() : uint { return _level; }
	
	// enemy : Object = {level, hp, attack, exp, count}
	public function MSLogic(w : uint, h : uint, enemies : Array, hp : int, lvs : Array)
	{
		_w = w;
		_h = h;
		_enemies = enemies;
		_hp = hp;
		_lvs = lvs;
		_exp = 0;
		_level = 1;
		
		var i : uint, j : uint;
		
		_map = new Vector.<Vector.<uint>>(_h);
		for(i = 0;i < _h;i++){
			_map[i] = new Vector.<uint>(_w);
			for(j = 0;j < _w;j++)_map[i][j] = 0;
		}
		_flipped = new Vector.<Vector.<uint>>(_h);
		for(i = 0;i < _h;i++){
			_flipped[i] = new Vector.<uint>(_w);
			for(j = 0;j < _w;j++)_flipped[i][j] = 0;
		}
		
		var places : Vector.<uint> = new Vector.<uint>(_w * _h);
		for(i = 0;i < _w * _h;i++)places[i] = i;
		for(i = 0;i < _w * _h - 1;i++){
			var ind : uint = uint(Math.random() * (_w * _h - i - 1)) + i + 1;
			var d : uint = places[ind];
			places[ind] = places[i];
			places[i] = d;
		}
		
		var p : uint = 0;
		for(i = 0;i < _enemies.length;i++){
			var enemy : Object = _enemies[i];
			for(j = 0;j < enemy.count;j++){
				var r : uint = places[p] / w;
				var c : uint = places[p] % w;
				_map[r][c] += (i + 1) << 8;
				for(var dr : int = -1;dr <= 1;dr++){
					for(var dc : int = -1;dc <= 1;dc++){
						if(dr == 0 && dc == 0)continue;
						if(isValid(r+dr, c+dc))_map[r+dr][c+dc] += enemy.level;
					}
				}
				p++;
			}
		}
	}
	
	public function isValid(r : int, c : int) : Boolean
	{
		return r >= 0 && r < _h && c >= 0 && c < _w;
	}
	
	// (r,c)をひっくり返す
	public function flip(r : uint, c : uint) : Boolean
	{
		if(_flipped[r][c] == 1)return false;
		var cell : uint = _map[r][c];
		var enemy : uint = _map[r][c] >> 8;
		var sumlv : uint = _map[r][c] & 0xff;
		if(enemy > 0){
			// 敵がいる場合
			_flipped[r][c] = 1;
			// 戦闘
			var res : int = combat(_hp, _level, _enemies[enemy-1].hp, _enemies[enemy-1].attack);
			if(res <= 0){
				_hp = 0;
				return true;
			}
			_hp = res;
			_exp += _enemies[enemy-1].exp;
			// レベルアップ
			if(_exp >= _lvs[_level - 1]){
				_level++;
			}
		}
		
		if(sumlv == 0){
			// レベル合計が0の場合、敵のいないまわり1マスを開く
			var chainFlips : Array = [[r, c]];
			 
			// マス開きの連鎖
			while(chainFlips.length > 0){
				var pos : Array = chainFlips.pop();
				if(_flipped[pos[0]][pos[1]] == 1)continue;
				if((_map[pos[0]][pos[1]] >> 8) > 0)continue;
				_flipped[pos[0]][pos[1]] = 1; 
				if(_map[pos[0]][pos[1]] == 0){
					for(var dr : int = -1;dr <= 1;dr++){
						for(var dc : int = -1;dc <= 1;dc++){
							if(dr == 0 && dc == 0)continue;
							if(isValid(pos[0]+dr, pos[1]+dc))chainFlips.push([pos[0]+dr, pos[1]+dc]);
						}
					}
				}
			}
		}else{
			_flipped[r][c] = 1;
		}
		return true;
	}
	
	// 戦闘
	public static function combat(shp : int, satk : int, ehp : int, eatk : int) : int
	{
		while(true){
			ehp -= satk;
			if(ehp <= 0)break;
			
			shp -= eatk;
			if(shp <= 0)break;
		}
		return (shp > 0 ? shp : 0) - (ehp > 0 ? ehp : 0);
	}
}