Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- //
- var Goban = function( conf ) {
- this.parent = $(document.body);
- this.lines = 19;
- this.cellwh = 38;
- this.palette = 1;
- this.need_chars = true;
- this.configure(conf);
- };
- var c = Goban;
- var p = c.prototype;
- c.colors = ["#000",0,0,0,0,0,"#FFF"];
- c.chars = "*ABCDEFGHJKLMNOPQRSTUVWXYZ".split("");
- c.ntoc = function( n ) {
- return n < c.chars.length ? c.chars[n] : n-25;
- };
- p.build = function() {
- this.draw_ban();
- this.draw_lines();
- this.draw_dots();
- this.draw_chars();
- this.set_palette(this.palette);
- this.init_grid();
- this.bind_events();
- };
- p.destroy = function() {
- this.ban.remove();
- };
- p.configure = function( conf ) {
- $.extend(this, conf);
- this.lines = this.lines < 3 ? 3 : (this.lines > 99 ? 99 : this.lines);
- this.padding = Math.ceil(this.cellwh/2+6);
- if ( this.need_chars ) this.padding += 18;
- this.stonewh = this.cellwh-2;
- if ( this.stonewh%2==0 ) this.stonewh--;
- };
- p.draw_ban = function() {
- this.ban = $("<div/>").css({
- width: this.padding * 2 + this.lines + this.cellwh * (this.lines-1),
- height: this.padding * 2 + this.lines + this.cellwh * (this.lines-1),
- }).addClass("Goban").appendTo(this.parent);
- this.ban.disableSelection();
- this.ban.on("contextmenu", function(){return false;});
- };
- p.draw_lines = function() {
- for ( var i=1; i<this.lines; ++i ) {
- $("<div/>").css({
- top: this.padding,
- left: this.padding,
- width: this.cellwh * i + i-1,
- height: this.cellwh * i + i-1,
- }).addClass("line").appendTo(this.ban).
- attr("i",i).attr("tl",true);
- $("<div/>").css({
- bottom: this.padding,
- right: this.padding,
- width: this.cellwh * i + i-1,
- height: this.cellwh * i + i-1,
- }).addClass("line").appendTo(this.ban).
- attr("i",i);
- }
- };
- p.draw_dots = function() {
- var n = this.lines;
- if ( n==5 ) {
- this.add_dot(n/2, n/2);
- } else if ( n>=7 ) {
- var step = n<=9 ? 2 : 3;
- this.add_dot(1+step, 1+step);
- this.add_dot(n-step, 1+step);
- this.add_dot(1+step, n-step);
- this.add_dot(n-step, n-step);
- if ( n>=13 && n%2 ) {
- this.add_dot(n/2, n/2);
- this.add_dot(n/2, 1+step);
- this.add_dot(n/2, n-step);
- this.add_dot(1+step, n/2);
- this.add_dot(n-step, n/2);
- }
- }
- };
- p.add_dot = function( x, y ) {
- x = Math.ceil(x);
- y = Math.ceil(y);
- $("<div/>").addClass("dot").appendTo(this.ban).
- attr("x",x).attr("y",y);
- };
- p.draw_chars = function() {
- if ( !this.need_chars ) return;
- for ( var i=1; i<=this.lines; ++i ) {
- $("<div/>").text(i).css({
- bottom: this.padding - 6 + (i-1) * this.cellwh + i-1,
- left: 4,
- }).addClass("char").appendTo(this.ban).
- attr("i",i).attr("btm",true);
- $("<div/>").text(i).css({
- bottom: this.padding - 6 + (i-1) * this.cellwh + i-1,
- right: 4,
- }).addClass("char").appendTo(this.ban).
- attr("i",i).attr("btm",true);
- $("<div/>").text(c.ntoc(i)).css({
- top: 5,
- left: this.padding - 8 + (i-1) * this.cellwh + i-1,
- }).addClass("char").appendTo(this.ban).
- attr("i",i);
- $("<div/>").text(c.ntoc(i)).css({
- bottom: 5,
- left: this.padding - 8 + (i-1) * this.cellwh + i-1,
- }).addClass("char").appendTo(this.ban).
- attr("i",i);
- }
- };
- p.resize = function( conf ) {
- var s,x,y;
- var self = this;
- this.configure(conf);
- var chars = this.ban.children(".char");
- if ( this.need_chars && chars.length==0 ) {
- this.draw_chars();
- this.set_palette(this.palette);
- }
- chars.css("display", this.need_chars ? "block" : "none");
- this.ban.css({
- width: this.padding * 2 + this.lines + this.cellwh * (this.lines-1),
- height: this.padding * 2 + this.lines + this.cellwh * (this.lines-1),
- });
- this.ban.children(".line").each(function() {
- var o = $(this);
- var i = parseInt(o.attr("i"));
- var tl = o.attr("tl");
- var css = {
- width: self.cellwh * i + i-1,
- height: self.cellwh * i + i-1,
- };
- css[tl?"top":"bottom"] = self.padding;
- css[tl?"left":"right"] = self.padding;
- o.css(css);
- });
- this.ban.children(".dot").each(function() {
- var o = $(this);
- var x = parseInt(o.attr("x"));
- var y = parseInt(o.attr("y"));
- var color = c.colors[self.palette] || c.colors[0];
- var indent = color==c.colors[0] ? 2 : 3;
- var wh = color==c.colors[0] ? 5 : 7;
- o.css({
- top: self.padding - indent + (y-1)*self.cellwh + y-1,
- left: self.padding - indent + (x-1)*self.cellwh + x-1,
- width: wh,
- height: wh,
- borderRadius: wh,
- });
- });
- this.ban.children(".char").each(function() {
- var o = $(this);
- var i = parseInt(o.attr("i"));
- var btm = o.attr("btm");
- var css = {};
- if ( btm ) {
- css.bottom = self.padding - 6 + (i-1) * self.cellwh + i-1;
- } else {
- css.left = self.padding - 8 + (i-1) * self.cellwh + i-1;
- }
- o.css(css);
- });
- for ( x=0; x<this.lines; ++x ) {
- for ( y=0; y<this.lines; ++y ) {
- s = this.grid[x][y];
- if ( s ) {
- var shadow = s.color=="w" ?
- (this.stonewh/3)+"px #AAA":
- this.stonewh+"px #000";
- s.obj.css({
- top: this.padding - this.stonewh/2 + y*this.cellwh + y,
- left: this.padding - this.stonewh/2 + x*this.cellwh + x,
- width: this.stonewh,
- height: this.stonewh,
- borderRadius: this.stonewh,
- boxShadow: "2px 2px 2px rgba(0,0,0,0.5), " +
- "inset 0 0 "+shadow,
- });
- }
- }
- }
- };
- p.set_palette = function( palette ) {
- this.palette = palette;
- var color = c.colors[palette] || c.colors[0];
- this.ban.css("background-image", palette>0?"url(img/bg"+palette+".jpg)":"none");
- this.ban.children(".line").css("border-color", color);
- this.ban.children(".dot").css({ background:color, boxShadow:"0 0 1px "+color });
- this.ban.children(".char").css("color", color);
- var self = this;
- this.ban.children(".dot").each(function() {
- var o = $(this);
- var x = parseInt(o.attr("x"));
- var y = parseInt(o.attr("y"));
- var color = c.colors[self.palette] || c.colors[0];
- var indent = color==c.colors[0] ? 2 : 3;
- var wh = color==c.colors[0] ? 5 : 7;
- o.css({
- top: self.padding - indent + (y-1)*self.cellwh + y-1,
- left: self.padding - indent + (x-1)*self.cellwh + x-1,
- width: wh,
- height: wh,
- borderRadius: wh,
- });
- });
- };
- p.bind_events = function() {
- var self = this;
- this.ban.mousedown(function( e ) {
- var x = Math.round((e.pageX - self.ban.offset().left - self.padding) / (self.cellwh+1));
- var y = Math.round((e.pageY - self.ban.offset().top - self.padding) / (self.cellwh+1));
- if ( e.which===1 ) {
- self.add_stone(x, y, self.game.turn);
- }
- });
- };
- p.init_grid = function() {
- var x,y;
- this.grid = [];
- for ( x=0; x<this.lines; ++x ) {
- this.grid[x] = [];
- for ( y=0; y<this.lines; ++y ) {
- this.grid[x][y] = false;
- }
- }
- };
- p.isongrid = function( x, y ) {
- return ( x>=0 && x<this.lines && y>=0 && y<this.lines );
- };
- p.add_stone = function( x, y, color ) {
- if ( !this.isongrid(x,y) ) {
- return;//this.game.onerror("камни нельзя размещать за пределами сетки");
- }
- if ( this.grid[x][y] ) {
- return this.game.onerror("камни нельзя размещать друг на друге");
- }
- var bgcolor = color=="w" ? "#FFF" : "#454545";
- var shadow = color=="w" ?
- (this.stonewh/3)+"px #AAA":
- this.stonewh+"px #000";
- var obj = $("<div/>").css({
- top: this.padding - this.stonewh/2 + y*this.cellwh + y,
- left: this.padding - this.stonewh/2 + x*this.cellwh + x,
- width: this.stonewh,
- height: this.stonewh,
- borderRadius: this.stonewh,
- background: bgcolor,
- boxShadow: "2px 2px 2px rgba(0,0,0,0.5), " +
- "inset 0 0 "+shadow,
- }).addClass("stone").appendTo(this.ban);
- var stone = { x:x, y:y, color:color, obj:obj, info:{} };
- this.grid[x][y] = stone;
- var rollback_reason = this.remove_dead_stones(stone);
- if ( rollback_reason ) {
- this.game.onerror(rollback_reason);
- this.grid[x][y] = false;
- obj.remove();
- } else {
- this.game.onturn(color);
- }
- };
- p.clean_stones = function() {
- var s,x,y;
- for ( x=0; x<this.lines; ++x ) {
- for ( y=0; y<this.lines; ++y ) {
- s = this.grid[x][y];
- if ( s ) s.info = {};
- }
- }
- };
- p.add_lps_enemy = function( lps_enemies, lps, x, y ) {
- if ( this.isongrid(x,y) ) {
- var s = this.grid[x][y];
- if ( s && s.color != lps.color ) {
- lps_enemies.push(s);
- s.info.lps_enemy_n = lps_enemies.length; // нумерация с 1 !!!!
- }
- }
- };
- // rollback: false - no, text - true
- p.remove_dead_stones = function( lps ) { // lps = last placed stone
- var s,x,y;
- var dead;
- var lps_enemies = []; // вражеские камни, лежащие вплотную к lps, которые нужно проверить на жизнеспособность
- var lps_enemies_killed = 0;
- this.clean_stones();
- // найти все вражеские камни, лежащие вплотную к lps
- x=lps.x; y=lps.y;
- this.add_lps_enemy(lps_enemies, lps, x+1, y);
- this.add_lps_enemy(lps_enemies, lps, x-1, y);
- this.add_lps_enemy(lps_enemies, lps, x, y+1);
- this.add_lps_enemy(lps_enemies, lps, x, y-1);
- while ( lps_enemies.length > 0 ) {
- s = lps_enemies.pop();
- if ( !s ) continue;
- dead = this.check_s_life(s, lps_enemies);
- if ( dead ) {
- lps_enemies_killed++;
- this.kill_group(dead);
- }
- }
- if ( lps_enemies_killed==0 ) {
- dead = this.check_s_life(lps, lps_enemies);
- if ( dead ) {
- if ( !this.game.allow_suicide ) {
- return "суицид запрещён правилами";
- } else if ( dead.length == 1 ) {
- return "ход не имеет смысла: камень будет сразу съеден";
- } else {
- this.kill_group(dead);
- }
- }
- }
- };
- p.kill_group = function( group ) {
- for ( var i=0; i<group.length; ++i ) {
- var s = group[i];
- this.grid[s.x][s.y] = false;
- this.game.oncapture(s);
- s.obj.remove();
- }
- };
- // проверить жизнеспособность группы, содержащей камень s
- // удалить если нет дыханий
- // вернуть инфу о том жива ли группа
- p.check_s_life = function( s, lps_enemies ) {
- var s,x,y;
- var dame = 0;
- var friends = [];
- var dead = []; // полный список, если нужно будет убить
- s.info.is_friend = true;
- friends.push(s);
- dead.push(s);
- while ( friends.length > 0 ) {
- s = friends.pop();
- x=s.x; y=s.y;
- dame += this.check_s_near(lps_enemies, friends, dead, s, x+1, y);
- dame += this.check_s_near(lps_enemies, friends, dead, s, x-1, y);
- dame += this.check_s_near(lps_enemies, friends, dead, s, x, y+1);
- dame += this.check_s_near(lps_enemies, friends, dead, s, x, y-1);
- }
- if ( dame > 0 ) dead = false;
- return dead;
- };
- p.check_s_near = function( lps_enemies, friends, dead, s, x, y ) {
- if ( !this.isongrid(x,y) ) return 0; // border
- var friend = this.grid[x][y];
- if ( !friend ) return 1; // empty, +1 dame
- if ( s.color != friend.color ) return 0; // enemy
- if ( friend.info.lps_enemy_n ) {
- lps_enemies[friend.info.lps_enemy_n-1] = false;
- }
- if ( !friend.info.is_friend ) {
- friend.info.is_friend = true;
- friends.push(friend);
- dead.push(friend);
- }
- return 0; // friend
- };
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement