Skip to content

Commit

Permalink
Refactor iuse_software_lightson
Browse files Browse the repository at this point in the history
Use points instead of int pairs, point arithmetics.
Several helper methods added.
  • Loading branch information
AMurkin authored and kevingranade committed Apr 27, 2020
1 parent 7a0d2aa commit 4f0d7a9
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 38 deletions.
83 changes: 49 additions & 34 deletions src/iuse_software_lightson.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,10 @@ void lightson_game::new_level()
const int half_perimeter = rng( 8, 11 );
const int lvl_width = rng( 4, 6 );
const int lvl_height = half_perimeter - lvl_width;
level_size = std::make_pair( lvl_height, lvl_width );
level_size = point( lvl_width, lvl_height );
level.resize( lvl_height * lvl_width );

const int steps_rng = half_perimeter / 2.0 + rng_float( 0, 2 );
const int steps_rng = half_perimeter / 2.0 + rng_float( 0.0, 2.0 );
generate_change_coords( steps_rng );

reset_level();
Expand All @@ -37,26 +37,41 @@ void lightson_game::reset_level()
std::fill( level.begin(), level.end(), true );

// change level
std::for_each( change_coords.begin(), change_coords.end(), [this]( std::pair<int, int> &p ) {
this->position = std::make_pair( p.first, p.second );
toggle_lights();
std::for_each( change_coords.begin(), change_coords.end(), [this]( point & p ) {
toggle_lights_at( p );
} );

position = std::make_pair( 0, 0 );
position = point_zero;

werase( w );
draw_border( w );
}

bool lightson_game::get_value_at( const point &pt )
{
return level[pt.y * level_size.x + pt.x];
}

void lightson_game::set_value_at( const point &pt, bool value )
{
level[pt.y * level_size.x + pt.x] = value;
}

void lightson_game::toggle_value_at( const point &pt )
{
set_value_at( pt, !get_value_at( pt ) );
}

void lightson_game::draw_level()
{
for( int i = 0; i < level_size.first; i++ ) {
for( int j = 0; j < level_size.second; j++ ) {
bool selected = position.first == i && position.second == j;
bool on = level[i * level_size.second + j];
for( int i = 0; i < level_size.y; i++ ) {
for( int j = 0; j < level_size.x; j++ ) {
point current = point( j, i );
bool selected = position == current;
bool on = get_value_at( current );
const nc_color fg = on ? c_white : c_dark_gray;
const char symbol = on ? '#' : '-';
mvwputch( w, point( j + 1, i + 1 ), selected ? hilite( c_white ) : fg, symbol );
mvwputch( w, current + point_south_east, selected ? hilite( c_white ) : fg, symbol );
}
}
wrefresh( w );
Expand All @@ -65,16 +80,15 @@ void lightson_game::draw_level()
void lightson_game::generate_change_coords( int changes )
{
change_coords.resize( changes );
const int size = level_size.first * level_size.second;
const int size = level_size.y * level_size.x;

std::pair< int, int > candidate;
point candidate;
for( int k = 0; k < changes; k++ ) {
do {
const int candidate_index = rng( 0, size - 1 );

const int col = candidate_index % level_size.second;
const int row = ( candidate_index - col ) / level_size.second;
candidate = std::make_pair( row, col );
candidate.x = candidate_index % level_size.x;
candidate.y = ( candidate_index - candidate.x ) / level_size.x;
// not accept repeatable coordinates
} while( !( k == 0 ||
std::find( change_coords.begin(), change_coords.end(), candidate ) == change_coords.end() ) );
Expand All @@ -91,24 +105,25 @@ bool lightson_game::check_win()

void lightson_game::toggle_lights()
{
const int row = position.first;
const int col = position.second;
const int height = level_size.first;
const int width = level_size.second;
toggle_lights_at( position );
}

void lightson_game::toggle_lights_at( const point &pt )
{
toggle_value_at( pt );

if( row > 0 ) {
level[( row - 1 ) * width + col] = !level[( row - 1 ) * width + col]; // N
if( pt.y > 0 ) {
toggle_value_at( pt + point_north );
}
level[row * width + col] = !level[row * width + col]; // x
if( row < height - 1 ) {
level[( row + 1 ) * width + col] = !level[( row + 1 ) * width + col]; // S
if( pt.y < level_size.y - 1 ) {
toggle_value_at( pt + point_south );
}

if( col > 0 ) {
level[row * width + ( col - 1 )] = !level[row * width + ( col - 1 )]; // W
if( pt.x > 0 ) {
toggle_value_at( pt + point_west );
}
if( col < width - 1 ) {
level[row * width + ( col + 1 )] = !level[row * width + ( col + 1 )]; // E
if( pt.x < level_size.x - 1 ) {
toggle_value_at( pt + point_east );
}
}

Expand All @@ -129,9 +144,9 @@ int lightson_game::start_game()
ctxt.register_action( "QUIT" );

std::vector<std::string> shortcuts;
shortcuts.push_back( _( "<spacebar or 5> toggle lights" ) ); // '5': toggle
shortcuts.push_back( _( "<r>eset" ) ); // 'r': reset
shortcuts.push_back( _( "<q>uit" ) ); // 'q': quit
shortcuts.push_back( _( "<spacebar or 5> toggle lights" ) );
shortcuts.push_back( _( "<r>eset" ) );
shortcuts.push_back( _( "<q>uit" ) );

int iWidth = 0;
for( auto &shortcut : shortcuts ) {
Expand Down Expand Up @@ -168,8 +183,8 @@ int lightson_game::start_game()
}
std::string action = ctxt.handle_input();
if( const cata::optional<tripoint> vec = ctxt.get_direction( action ) ) {
position.first = std::min( std::max( position.first + vec->y, 0 ), level_size.first - 1 );
position.second = std::min( std::max( position.second + vec->x, 0 ), level_size.second - 1 );
position.y = clamp( position.y + vec->y, 0, level_size.y - 1 );
position.x = clamp( position.x + vec->x, 0, level_size.x - 1 );
} else if( action == "TOGGLE_SPACE" || action == "TOGGLE_5" ) {
toggle_lights();
win = check_win();
Expand Down
13 changes: 9 additions & 4 deletions src/iuse_software_lightson.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,19 @@
#include <utility>

#include "cursesdef.h"
#include "point.h"

class lightson_game
{
private:
catacurses::window w_border;
catacurses::window w;
// rows, columns
std::pair< int, int > level_size;
std::vector< bool > level;
std::vector< std::pair< int, int > > change_coords;
point level_size;
std::vector<bool> level;
std::vector<point> change_coords;
// row, column
std::pair< int, int > position;
point position;
bool win;

void new_level();
Expand All @@ -26,6 +27,10 @@ class lightson_game
void draw_level();
bool check_win();
void toggle_lights();
void toggle_lights_at( const point &pt );
bool get_value_at( const point &pt );
void set_value_at( const point &pt, bool value );
void toggle_value_at( const point &pt );

public:
int start_game();
Expand Down

0 comments on commit 4f0d7a9

Please sign in to comment.