📄 insight.java
字号:
{
component.getBounds ( bounds );
// paint the background
g.setColor ( Color.BLACK );
g.fillRect ( bounds.x, bounds.y, bounds.width, bounds.height );
// paint the kobolds, goblins, and walls
plotThings ( bounds, g, ELEMENT_COLOR [ KOBOLD ], kobolds );
plotThings ( bounds, g, ELEMENT_COLOR [ GOBLIN ], goblins );
plotThings ( bounds, g, ELEMENT_COLOR [ WALL ], walls );
// paint the status
g.setColor ( java.awt.Color.white );
g.setFont ( font );
g.drawString (
createStatusString (
kobolds_killed,
goblins_killed,
kobolds_killed_by_goblins,
goblins_killed_by_kobolds ),
bounds.x + 10, bounds.y + bounds.height - 10 );
}
//////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////
public void itemStateChanged ( ItemEvent itemEvent )
//////////////////////////////////////////////////////////////////////
{
Object item = itemEvent.getItem ( );
if ( item == learningOnCheckBox )
{
goblin_learning_on = learningOnCheckBox.isSelected ( );
resetStats ( );
}
}
public void actionPerformed ( ActionEvent actionEvent )
//////////////////////////////////////////////////////////////////////
{
Object source = actionEvent.getSource ( );
if ( source == scrambleBrainsButton )
{
goblin_brain.weights_randomize_uniform ( -1.0, 1.0 );
resetStats ( );
}
else if ( source instanceof JButton )
{
int buttonIndex = -1;
JButton button = null;
for ( int i = 0; i < directionButtons.length; i++ )
{
if ( source == directionButtons [ i ] )
{
buttonIndex = i;
button = ( JButton ) source;
break;
}
}
direction_button_element [ buttonIndex ]++;
if ( direction_button_element [ buttonIndex ] >= ELEMENT_COUNT )
{
direction_button_element [ buttonIndex ] = 0;
}
Color backgroundColor
= ELEMENT_COLOR [ direction_button_element [ buttonIndex ] ];
Color foregroundColor = Color.BLACK;
if ( backgroundColor == Color.BLACK )
{
foregroundColor = Color.WHITE;
}
button.setBackground ( backgroundColor );
button.setForeground ( foregroundColor );
button.setText (
"" + ELEMENT_NAME [ direction_button_element [
buttonIndex ] ] );
}
}
//////////////////////////////////////////////////////////////////////
// interface ComponentListener methods
//////////////////////////////////////////////////////////////////////
public void componentResized ( ComponentEvent componentEvent )
//////////////////////////////////////////////////////////////////////
{
Object source = componentEvent.getSource ( );
if ( source == animatedComponent )
{
Rectangle bounds = animatedComponent.getBounds ( );
FontLib.setMaxFont (
animatedComponent,
createStatusString ( 99999, 99999, 99999, 99999 ),
FONT_NAME,
FONT_STYLE,
bounds.width,
bounds.height );
}
}
public void componentHidden ( ComponentEvent componentEvent )
//////////////////////////////////////////////////////////////////////
{
}
public void componentMoved ( ComponentEvent componentEvent )
//////////////////////////////////////////////////////////////////////
{
}
public void componentShown ( ComponentEvent componentEvent )
//////////////////////////////////////////////////////////////////////
{
}
//////////////////////////////////////////////////////////////////////
// private methods
//////////////////////////////////////////////////////////////////////
private void resetStats ( )
//////////////////////////////////////////////////////////////////////
{
kobolds_killed = 0;
goblins_killed = 0;
kobolds_killed_by_goblins = 0;
goblins_killed_by_kobolds = 0;
}
private static String createStatusString (
long kobolds_killed,
long goblins_killed,
long kobolds_killed_by_goblins,
long goblins_killed_by_kobolds )
//////////////////////////////////////////////////////////////////////
{
return "Dead Kobolds: "
+ kobolds_killed
+ " "
+ "Dead Goblins: " + goblins_killed
+ " "
+ "Kobolds killed by Goblins: " + kobolds_killed_by_goblins
+ " "
+ "Goblins killed by Kobolds: " + goblins_killed_by_kobolds;
}
private void direction_button_update ( )
//////////////////////////////////////////////////////////////////////
{
Matrix direction_probabilities
= calculateDirectionProbabilities (
direction_button_element );
for ( int i = 0; i < directionButtons.length; i++ )
{
directionButtons [ i ].setText (
"" + ELEMENT_NAME [ direction_button_element [ i ] ]
+ ": "
+ ( int ) ( direction_probabilities.data [ i ] [ 0 ]
* 100.0 ) + "%" );
}
}
private Matrix calculateDirectionProbabilities (
int [ ] typeVision )
//////////////////////////////////////////////////////////////////////
{
for ( int i = 0; i < typeVision.length; i++ )
{
for ( int j = 0; j < ELEMENT_COUNT; j++ )
{
goblin_brain_inputs.data
[ ELEMENT_COUNT * i + j ] [ 0 ]
= ( typeVision [ i ] == j ) ? 1.0 : 0.0;
}
}
Matrix leanings = goblin_brain.forward_pass ( goblin_brain_inputs );
return leanings.divide ( leanings.sum ( ) );
}
private Point goblin_move_direction ( Thing goblin )
//////////////////////////////////////////////////////////////////////
{
int [ ] typeVision = new int [ DIRECTIONS.length ];
for ( int i = 0; i < typeVision.length; i++ )
{
typeVision [ i ] = ETHER;
int x = goblin.x + DIRECTIONS [ i ].x;
int y = goblin.y + DIRECTIONS [ i ].y;
if ( ( x >= 0 )
&& ( x < space_contents.length )
&& ( y >= 0 )
&& ( y < space_contents [ 0 ].length ) )
{
Thing content = space_contents [ x ] [ y ];
if ( content != null )
{
typeVision [ i ] = content.type;
}
}
}
Matrix direction_probabilities
= calculateDirectionProbabilities ( typeVision );
double sum = 0.0;
double r = Croft_Random.uniform ( 0.0, 1.0 );
for ( int i = 0; i < direction_probabilities.rows; i++ )
{
if ( r < sum + direction_probabilities.data [ i ] [ 0 ] )
{
goblin_best_direction = i;
break;
}
sum += direction_probabilities.data [ i ] [ 0 ];
}
return new Point (
DIRECTIONS [ goblin_best_direction ].x,
DIRECTIONS [ goblin_best_direction ].y );
}
private void goblin_move_reinforce ( double target )
//////////////////////////////////////////////////////////////////////
{
Matrix desired_directions = new Matrix (
goblin_brain.outputs.m [ goblin_brain.layers - 1 ] );
if ( goblin_learning_on )
{
// why are we using supervised instead of reinforcement learning?
for ( int i = 0; i < DIRECTIONS.length; i++ )
{
desired_directions.data [ i ] [ 0 ] = 1.0 - target;
}
desired_directions.data [ goblin_best_direction ] [ 0 ] = target;
goblin_brain.backward_pass ( desired_directions );
goblin_brain.weights_update ( );
}
}
private void moveGoblin ( Thing goblin )
//////////////////////////////////////////////////////////////////////
{
Point move_direction = goblin_move_direction ( goblin );
int x = goblin.x + move_direction.x;
int y = goblin.y + move_direction.y;
boolean abortMove
= ( x < 0 )
|| ( x >= BATTLEFIELD_WIDTH )
|| ( y < 0 )
|| ( y >= BATTLEFIELD_HEIGHT );
if ( !abortMove )
{
Thing content = space_contents [ x ] [ y ];
if ( content == null )
{
}
else if ( content.type == KOBOLD )
{
killThing ( content );
goblin_move_reinforce ( 1.0 );
kobolds_killed_by_goblins++;
}
else if ( content.type == GOBLIN )
{
killThing ( content );
goblin_move_reinforce ( 0.0 );
}
else if ( content.type == WALL )
{
killThing ( goblin );
goblin_move_reinforce ( 0.0 );
abortMove = true;
}
else
{
throw new RuntimeException ( "unknown Thing type" );
}
}
if ( !abortMove )
{
space_contents [ goblin.x ] [ goblin.y ] = null;
goblin.x = x;
goblin.y = y;
space_contents [ x ] [ y ] = goblin;
}
}
private void moveKobold ( Thing kobold )
//////////////////////////////////////////////////////////////////////
{
// move randomly
int rd = ( int ) RandomLib.roll ( 1, 8, -1 );
Point move_direction
= new Point ( DIRECTIONS [ rd ].x, DIRECTIONS [ rd ].y );
int x = kobold.x + move_direction.x;
int y = kobold.y + move_direction.y;
boolean abortMove
= ( x < 0 )
|| ( x >= BATTLEFIELD_WIDTH )
|| ( y < 0 )
|| ( y >= BATTLEFIELD_HEIGHT );
if ( !abortMove )
{
Thing content = space_contents [ x ] [ y ];
if ( content == null )
{
}
else if ( content.type == GOBLIN )
{
killThing ( content );
goblins_killed_by_kobolds++;
}
else if ( content.type == KOBOLD )
{
killThing ( content );
}
else if ( content.type == WALL )
{
killThing ( kobold );
abortMove = true;
}
else
{
throw new RuntimeException ( "unknown Thing type" );
}
}
if ( !abortMove )
{
space_contents [ kobold.x ] [ kobold.y ] = null;
kobold.x = x;
kobold.y = y;
space_contents [ x ] [ y ] = kobold;
}
}
private void killThing ( Thing thing )
//////////////////////////////////////////////////////////////////////
{
if ( thing.type == GOBLIN )
{
goblins_killed++;
}
else if ( thing.type == KOBOLD )
{
kobolds_killed++;
}
space_contents [ thing.x ] [ thing.y ] = null;
// spawn a replacement
// why do we bother with isAlive flag?
putThingInRandomEmptySpace ( thing );
}
private void putThingInRandomEmptySpace ( Thing thing )
//////////////////////////////////////////////////////////////////////
{
int x;
int y;
while ( true )
{
x = ( int ) RandomLib.roll ( 1, BATTLEFIELD_WIDTH , -1 );
y = ( int ) RandomLib.roll ( 1, BATTLEFIELD_HEIGHT, -1 );
if ( space_contents [ x ] [ y ] == null )
{
break;
}
}
space_contents [ x ] [ y ] = thing;
thing.x = x;
thing.y = y;
}
private void plotThings (
Rectangle bounds,
Graphics graphics,
Color color,
Thing [ ] things )
//////////////////////////////////////////////////////////////////////
{
if ( things == null )
{
return;
}
for ( int i = 0; i < things.length; i++ )
{
Thing thing = things [ i ];
// Since they regenerate, is isAlive always true?
if ( thing.isAlive )
{
PlotLib.xy ( color, thing.x + 0.5, thing.y + 0.5,
bounds, graphics,
0, BATTLEFIELD_WIDTH, 0, BATTLEFIELD_HEIGHT, 1, true );
}
}
}
//////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -