您的位置:首页 > 运维架构 > Linux

Linux系统上Iptables实现端口转发的过程

2012-03-29 14:17 441 查看
      前一阵子为了练手,写了一个连连看的小游戏,主要的设计为棋盘类,位置类,棋子类,核心算法包,一些自定义事件和资源类。我称连连看中被点击的按钮为棋子,下面那个看不见的布局要用的东西我成为棋盘。这样设计一个小游戏主要也是为了降低耦合性,每个部分可以比较独立的变化而不影响其他的部分。比如,棋子随意变,棋盘也可以变为圆形,甚至五角星的,只要改变一个字段就可以方便的更改棋子的皮肤或者音乐。

      核心算法主要写了一个随机分配的算法,就是保证每次玩的时候最后都要正好能全部消灭。连连看的死局这里暂时没有考虑。还有一个就是把判断两个棋子是否可以消除,我没有用网上介绍的递归算法,我用的“十字通路法”,我自己起的名字哈。我想这样来解释会清楚一些:

十字通路:

每个棋子拥有一个十字通路,就是它可以到达的上下左右,可以到达的意思就是路过的位置是空的或者是不可见的,类似一个十字一样。当然也可能不是“十”字,或者是个"T",总之就是遍历上下左右,碰壁为止,并整理记录下来X轴通路和Y轴通路。

判断两个棋子是否可以消除的条件:

1.两个棋子的图案必须要相同。

2.两个棋子最多通过两次“拐弯”可以到达。理解成我所谓的十字通路就是两个棋子的X(Y)轴通路可以直线相连。

以下是我用来测试的代码

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
creationComplete="init()"
layout="vertical"
width="100%"
height="100%"
backgroundGradientAlphas="[0.8, 0.9]"
backgroundGradientColors="[#736D6D, #070707]"
xmlns:ns1="*"
xmlns:ns2="com.chess.*"
xmlns:ns3="com.board.*">
<mx:Style source="myCSS.css"/>
<mx:Script>
<![CDATA[
import mx.events.CloseEvent;
import mx.core.UIComponent;
import mx.controls.Alert;
import com.coreAlg.CheckBoard;
import com.coreAlg.connect.Connect;
import com.coreAlg.connect.GetCross;
import embed.embedImage.EtImage;
import com.board.Board;
import com.chess.Chess;
import mx.containers.HBox;
import MyEvent.MyClickEvent;
import com.position.Position;
import mx.containers.Canvas;
import embed.embedSound.HappySound;
//private var position:Position;
private var board:Board=new Board();
public var eee:EtImage=EtImage.getInstance(); //图片资源类
//程序里有个缓冲区
private var firstImageSource:Class=null; //上一个棋子的图片源
private var firstX:int=-1; //上一个棋子的X坐标
private var firstY:int=-1; //上一个棋子的Y坐标
private var tempImageSource:Class=null; //储存刚刚点击棋子的图片源
private var tempX:int=-1; //储存刚刚点击棋子的X坐标
private var tempY:int=-1; //储存刚刚点击棋子的Y坐标
private var getc:GetCross=GetCross.getInstance();
private var conn:Connect=Connect.getInstance();
private var check:CheckBoard=CheckBoard.getInstance();
private var pan:UIComponent=new UIComponent(); //画路径的画笔
private var sound:HappySound=HappySound.getInstance();
private var pathArray:Array;
private var pathPan:UIComponent=new UIComponent();
private var pathTimer:Timer=new Timer(50);
private var myTimer:Timer=new Timer(1000);
private var totalTime:int=0;
private var xN:int = 6;
private var yN:int = 5;

//private var board:Board;
private function init():void
{
board.xNum=xN; //宽
board.yNum=yN; //高
board.nkind=5; //图案种数
board.x=0;
board.y=0;
myCanvas.addChild(board);
myCanvas.addChild(pan);
MyClickEvent.dispatcher.addEventListener(MyClickEvent.CLICK_IMAGE, clickHandler);
this.addEventListener(MyClickEvent.CLICK_IMAGE, clickHandler);
myTimer.start();
myTimer.addEventListener(TimerEvent.TIMER, onTimer);
}

private function onTimer(event:TimerEvent):void
{
totalTime++;
}

private function alertClickHandler(event:CloseEvent):Boolean
{
if (event.detail == Alert.OK)
{
xN += 2;
yN += 2;
if(xN > 10)
{
Alert.show('thank u 4 play~!');
return false;
}
myTimer.stop();
myTimer.start();
myCanvas.removeChild(board);
board=new Board();
trace('board.chessCompleted:'+board.chessCompleted);
board.xNum=xN; //宽
board.yNum=yN; //高
board.nkind=xN; //图案种数
board.x=0;
board.y=0;
myCanvas.addChild(board);
return true;
}
return true;
}

private function clickHandler(event:MyClickEvent):void
{
tempX=event.x;
tempY=event.y;
var firPosition:Position=new Position(firstX, firstY);
var secPosition:Position=new Position(tempX, tempY);
//查看当前点击的通路数组
/* trace('xCross:');
var tttArray:Array=(getc.getCross((board.chessArray[event.y][event.x] as Chess), board)).getItemAt(0) as Array;
for (var ttt:int=0; ttt < tttArray.length; ttt++)
{
trace((tttArray[ttt] as Position).xPosition + '  ' + (tttArray[ttt] as Position).yPosition);
}
tttArray=(getc.getCross((board.chessArray[event.y][event.x] as Chess), board)).getItemAt(1) as Array;
trace('yCross:');
for (ttt=0; ttt < tttArray.length; ttt++)
{
trace((tttArray[ttt] as Position).xPosition + '  ' + (tttArray[ttt] as Position).yPosition);
} */
tempImageSource=(board.chessArray[event.y][event.x] as Chess).imageSource;
//如果缓存ID不为空 且 缓存ID和点击的目标不是同一个 且 缓存ID和目标ID有通路
if ((isValidPosition(firstX, firstY)) && (!equalPosition(tempX, tempY, firstX, firstY)) && (conn.connect(board, firPosition, secPosition)))
{

//画出路径,并消除那两个棋子,再清空路径数组
clearIcons.play([this]);
(board.chessArray[tempY][tempX] as Chess).disAppearState();
(board.chessArray[firstY][firstX] as Chess).disAppearState();
board.chessCompleted += 2;
drawPath();
//清空缓存
firstX=-1;
firstY=-1;
firstImageSource=null;
board.pathArray=new Array(); //清空path
if (check.checkComplete(board))
{
mx.controls.Alert.show("congratulations~,难度"+xN+'乘以'+yN+"    一共用时" + totalTime+'秒', '', Alert.OK, this, alertClickHandler);
}
}
else
{
//trace('最终匹配不成功');
//trace('*************************************************');
//没有匹配成功刷新缓存
if (firstX != -1 && !equalPosition(tempX, tempY, firstX, firstY))
{
(board.chessArray[firstY][firstX] as Chess).normalState();
}
firstImageSource=tempImageSource;
firstX=tempX;
firstY=tempY;
//	}
}
}

private function equalImageSource(tm:Class, fir:Class):Boolean
{
if (tm == fir)
{
//trace('图片相等');
return true;
}
//trace('图片不相等');
return false;
}

private function isValidPosition(tx:int, ty:int):Boolean
{
if (tx >= 0 && ty >= 0)
{
//trace('横纵坐标都大于0');
return true;
}
//trace('坐标小于0');
//trace('firstX:'+firstX+'   '+'firstY:'+firstY);
return false;
}

private function equalPosition(tx:int, ty:int, firx:int, firy:int):Boolean
{
if (tx == firx && ty == firy)
{
//trace('坐标相等');
return true;
}
//trace('坐标不相等');
return false;
}

private function drawPath():void
{
trace('board.pathArray.length:' + board.pathArray.length);
pathTimer.start();
pathArray=board.pathArray;
board.pathArray=null;
var step:Position=pathArray.shift() as Position;
trace('path.length:' + pathArray.length);
myCanvas.addChild(pathPan);
pathPan.graphics.clear();
pathPan.graphics.lineStyle(2, 0xFF0000);
pathPan.graphics.moveTo(board.x + board.leftGap + (step.xPosition + 1) * (board.chessWidth + 2) - board.chessWidth / 2, board.y + board.topGap + (step.yPosition + 1) * (board.chessHeight + 2) - board.chessHeight / 2);

pathTimer.addEventListener(TimerEvent.TIMER, drawLine)
//pathPan.addEventListener(Event.ENTER_FRAME,drawLine);
}

private function drawLine(event:Event):void
{
if (pathArray.length > 0)
{
var step:Position=pathArray.shift() as Position;
pathPan.graphics.lineTo(board.x + board.leftGap + (step.xPosition + 1) * (board.chessWidth + 2) - board.chessWidth / 2, board.y + board.topGap + (step.yPosition + 1) * (board.chessHeight + 2) - board.chessHeight / 2);
}
else
{
pathTimer.stop();
//pathPan.removeEventListener(Event.ENTER_FRAME,drawLine);
myCanvas.removeChild(pathPan);
}
}
]]>
</mx:Script>
<mx:Canvas id="myCanvas"
width="100%"
height="100%">

</mx:Canvas>
<mx:SoundEffect id="clearIcons"
duration="2000"
source="{sound.clearSound}"/>
</mx:Application>

 

附件是测试对应的.swf,资源都内嵌了
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: