Игра "Змейка" — различия между версиями

Материал из Department of Theoretical and Applied Mechanics
Перейти к: навигация, поиск
(Описание)
(Код программы)
 
(не показано 13 промежуточных версий 1 участника)
Строка 1: Строка 1:
 
== Описание ==
 
== Описание ==
Игра, в которой игрок управляет змейкой, которая ползает по плоскости, ограниченной стенками, и собирает еду, избегая столкновения с собственным хвостом и краями игрового поля.
+
В этой игре пользователь управляет змейкой, которая ползает по плоскости, ограниченной стенками, и собирает еду, избегая столкновения с собственным хвостом и краями игрового поля.
  
Исполнители: [http://tm.spbstu.ru/%D0%94%D0%B5%D0%BC%D0%B8%D0%BD%D0%B0_%D0%9A%D1%81%D0%B5%D0%BD%D0%B8%D1%8F Демина Ксения], [http://tm.spbstu.ru/%D0%9F%D1%80%D0%BE%D1%85%D0%BE%D1%80%D0%B5%D0%BD%D0%BA%D0%BE%D0%B2%D0%B0_%D0%98%D1%80%D0%B8%D0%BD%D0%B0 Прохоренкова И.Г.], [http://tm.spbstu.ru/%D0%9C%D0%B0%D0%BB%D1%8B%D1%88%D0%B5%D0%B2%D0%B0_%D0%92%D0%B5%D1%80%D0%BE%D0%BD%D0%B8%D0%BA%D0%B0 Малышева В.Н.]
+
Исполнители: [http://tm.spbstu.ru/%D0%94%D0%B5%D0%BC%D0%B8%D0%BD%D0%B0_%D0%9A%D1%81%D0%B5%D0%BD%D0%B8%D1%8F Демина К.В.], [http://tm.spbstu.ru/%D0%9F%D1%80%D0%BE%D1%85%D0%BE%D1%80%D0%B5%D0%BD%D0%BA%D0%BE%D0%B2%D0%B0_%D0%98%D1%80%D0%B8%D0%BD%D0%B0 Прохоренкова И.Г.], [http://tm.spbstu.ru/%D0%9C%D0%B0%D0%BB%D1%8B%D1%88%D0%B5%D0%B2%D0%B0_%D0%92%D0%B5%D1%80%D0%BE%D0%BD%D0%B8%D0%BA%D0%B0 Малышева В.Н.]
  
 
Группа 13632/1 Кафедра Теоретической механики.
 
Группа 13632/1 Кафедра Теоретической механики.
Строка 11: Строка 11:
 
Поле представляет собой прямоугольник, в пределах которого движется зеленая ячейка, являющаяся змейкой, и красные, синие и желтые ячейки, которые представляют собой еду для нее.
 
Поле представляет собой прямоугольник, в пределах которого движется зеленая ячейка, являющаяся змейкой, и красные, синие и желтые ячейки, которые представляют собой еду для нее.
 
== Визуализация ==
 
== Визуализация ==
{{#widget:Iframe |url=http://tm.spbstu.ru/htmlets/Demina_KV/zmeika.html |width=1100|height=2000|border=0 }}
+
{{#widget:Iframe |url=http://tm.spbstu.ru/htmlets/Demina_KV/zmeika.html |width=1100|height=800|border=0 }}
 +
== Код программы ==
 +
<div class="mw-collapsible mw-collapsed">
 +
<syntaxhighlight lang="javascript" line start="1" enclose="div">
 +
window.addEventListener("load",main,false);
 +
function main_code(){
 +
var ctx = SnakeS.getContext("2d");
 +
var h = SnakeS.height;
 +
var w = SnakeS.width;
 +
var n = 45;
 +
var intervalID;
 +
var direction = "left";
 +
var ms =200;
 +
var score = 0;
 +
var wCode = 87;
 +
var aCode = 65;
 +
var sCode = 83;
 +
var dCode = 68;
 +
var upCode = 38;
 +
var leftCode = 37;
 +
var downCode = 40;
 +
var rightCode = 39;
 +
var pause = false;
 +
function get_mouse_coords(e){
 +
var m = {};
 +
var rect = SnakeS.getBoundingClientRect();
 +
m.x = e.clientX - rect.left;
 +
m.y = e.clientY - rect.top;
 +
return m;
 +
}
 +
SnakeS.onclick = function(e){
 +
  var m = get_mouse_coords(e);
 +
  console.log(m.x, m.y);
 +
  if ((m.x>(w/2-95))&&(m.x<(w/2+95))&&(m.y>(h/2+30))&&(m.y<(h/2+70))) {
 +
  console.log(1);
 +
  location.reload();
 +
  }
 +
}
 +
var sl=1;
 +
var nofood = false;
 +
var nofoodno = false;
 +
var x = w/n;
 +
var y = h/n;
 +
console.log(x,y);
 +
function box(){
 +
  this.conteins = "empty";
 +
}
 +
function Snake(){
 +
  this.head = null;
 +
  this.tail = null;
 +
  this.body = [];
 +
  this.length = 1;
 +
}
 +
var field = [];
 +
for (var i=0; i<n; i++) {
 +
  var m = [];
 +
  for (var j=0; j<n; j++){
 +
  m.push(new box());
 +
  }
 +
  field.push(m);
 +
}
 +
var snake = new Snake();
 +
function finish() {
 +
  ctx.textAlign = 'center';
 +
  ctx.font = '30px Georgia';
 +
  pause = true;
 +
  console.error("Вы проиграли");
 +
  clearInterval(intervalID);
 +
  ctx.fillStyle = 'rgb(180, 234, 255)';
 +
  ctx.fillRect(0.25*w, 0.25*h, 0.5*w, 0.5*h);
 +
  ctx.strokeStyle = 'black';
 +
  ctx.strokeRect(0.25*w, 0.25*h, 0.5*w, 0.5*h);
 +
  ctx.fillStyle = 'black';
 +
  ctx.fillText('Вы проиграли!', w/2, h/2-40);
 +
  ctx.fillText('Ваш счет: '+score, w/2, h/2);
 +
  ctx.fillStyle = 'rgb(14, 151, 184)';
 +
  ctx.fillRect(w/2-95, h/2+30, 190, 40);
 +
  ctx.strokeRect(w/2-95, h/2+30, 190, 40);
 +
  ctx.fillStyle = 'black';
 +
  ctx.fillText('Сыграть еще', w/2, h/2+60);
 +
  console.info('rtr');
 +
}
 +
function CreateItem(item){
 +
  var i=Math.round(Math.random()*(n - 1));
 +
  var j=Math.round(Math.random()*(n - 1));
 +
  while (field [i][j].conteins != "empty"){
 +
    var i=Math.round(Math.random()*(n - 1));
 +
    var j=Math.round(Math.random()*(n - 1));
 +
  }
 +
  field [i][j].conteins = item;
 +
}
 +
function Init(){
 +
  var i=Math.round(Math.random()*(n - 1));
 +
  var j=Math.round(Math.random()*(n - 1));
 +
  field [i][j].conteins = "food";
 +
  var i=Math.round(Math.random()*(n - 1));
 +
  var j=Math.round(Math.random()*(n - 1));
 +
  while (field [i][j].conteins == "food"){
 +
    var i=Math.round(Math.random()*(n - 1));
 +
    var j=Math.round(Math.random()*(n - 1));
 +
  }
 +
  field [i][j].conteins = "snake";
 +
  snake.head = {x: i, y: j};
 +
  snake.tail = {x: i, y: j};
 +
  snake.body.push({x: i, y: j}) ;
 +
  console.log(direction, snake.body, snake.head);
 +
  CreateItem('nofood');
 +
}
 +
function Draw() {
 +
  for (var i=0; i<n; i++) {
 +
  for (var j=0; j<n; j++){
 +
    if (field[i][j].conteins == "empty") {
 +
    ctx.fillStyle = 'white';
 +
    ctx.fillRect(x*i, y*j, x, y);
 +
    }
 +
    if (field[i][j].conteins == "food") {
 +
    ctx.fillStyle = 'red';
 +
    ctx.fillRect(x*i, y*j, x, y);
 +
    ctx.strokeStyle = 'black';
 +
    ctx.strokeRect(x*i, y*j, x, y);
 +
    }
 +
    if (field[i][j].conteins == "snake") {
 +
    ctx.fillStyle = 'green';
 +
    ctx.fillRect(x*i, y*j, x, y);
 +
    ctx.strokeStyle = 'black';
 +
    ctx.strokeRect(x*i, y*j, x, y);
 +
    }
 +
    if (field[i][j].conteins == "nofood") {
 +
    ctx.fillStyle = 'blue';
 +
    ctx.fillRect(x*i, y*j, x, y);
 +
    ctx.strokeStyle = 'black';
 +
    ctx.strokeRect(x*i, y*j, x, y);
 +
    }
 +
    if (field[i][j].conteins == "nofoodno") {
 +
    ctx.fillStyle = 'yellow';
 +
    ctx.fillRect(x*i, y*j, x, y);
 +
    ctx.strokeStyle = 'black';
 +
    ctx.strokeRect(x*i, y*j, x, y);
 +
    }
 +
  }
 +
  }
 +
  document.getElementById('scre').innerHTML = score;
 +
}
 +
window.onkeydown = function(evt) {
 +
evt = evt || window.event;
 +
var charCode = evt.keyCode || evt.which;
 +
console.log(charCode);
 +
if (((charCode == wCode)||(charCode == upCode)) && direction != "down") {
 +
  direction = "up";
 +
}
 +
if (((charCode == sCode)||(charCode == downCode)) && direction != "up") {
 +
  direction = "down";
 +
}
 +
if (((charCode == aCode)||(charCode == leftCode)) && direction != "right") {
 +
  direction = "left";
 +
}
 +
if (((charCode == dCode)||(charCode == rightCode)) && direction != "left") {
 +
  direction = "right";
 +
}
 +
}
 +
function CheckLength() {
 +
  if ((score == 3) && (sl != 2)){
 +
  sl = 2;
 +
  ms = ms-100;
 +
  clearInterval(intervalID);
 +
  intervalID = setInterval(control, ms);
 +
  return ;
 +
  }
 +
  if ((score == 5 ) && (sl != 3)){
 +
  sl = 3;
 +
  ms = ms-50;
 +
  clearInterval(intervalID);
 +
  intervalID = setInterval(control, ms);
 +
  }
 +
}
 +
function Calcul(){
 +
  var next
 +
  try {
 +
  if (direction == "left") {
 +
  next = {x: snake.head.x-1, y: snake.head.y}
 +
  }
 +
  if (direction == "right") {
 +
  next = {x: snake.head.x+1, y: snake.head.y}
 +
  }
 +
  if (direction == "up") {
 +
  next = {x: snake.head.x, y: snake.head.y-1}
 +
  }
 +
  if (direction == "down" && snake.length == 1) {
 +
  next = {x: snake.head.x, y: snake.head.y+1}
 +
  }
 +
  if (direction == "down" && snake.length > 1) {
 +
  next = {x: snake.head.x, y: snake.head.y}
 +
  }
 +
  if (score > 5) {
 +
  if (next.x<0) {
 +
    next.x = n-1
 +
    console.log('TP')
 +
    }
 +
  if (next.y<0) {
 +
    next.y = n-1
 +
    console.log('TP')
 +
   
 +
  if (next.x>n-1) {
 +
    next.x = 0
 +
    console.log('TP')
 +
    }
 +
  if (next.y>n-1) {
 +
    next.y = 0
 +
    console.log('TP')
 +
    }
 +
  } else {
 +
  if (next.x<0) {
 +
    finish();
 +
    return;
 +
    }
 +
  if (next.y<0) {
 +
    finish();
 +
    return;
 +
    }
 +
  if (next.x>n-1) {
 +
    finish();
 +
    return;
 +
    }
 +
  if (next.y>n-1) {
 +
    finish();
 +
    return;
 +
    }
 +
  }
 +
  if (field[next.x][next.y].conteins == "snake") {
 +
  finish();
 +
  return;
 +
  }
 +
  if (field[next.x][next.y].conteins == "food") {
 +
  snake.body.push({x:next.x, y:next.y});
 +
  snake.head = {x:next.x, y:next.y};
 +
  field[next.x][next.y].conteins = "snake";
 +
  CreateItem ('food');
 +
  score++;
 +
  }
 +
  if (field[next.x][next.y].conteins == "nofoodno") {
 +
  snake.body.push({x:next.x, y:next.y});
 +
  snake.head = {x:next.x, y:next.y};
 +
  field[next.x][next.y].conteins = "snake";
 +
  field[snake.body[0].x][snake.body[0].y].conteins = "empty";
 +
  snake.body.shift();
 +
  if(snake.body.length!=1)
 +
    field[snake.body[0].x][snake.body[0].y].conteins = "empty";
 +
    snake.body.shift();
 +
  score++;
 +
  nofoodno=false;
 +
  }
 +
  if (field[next.x][next.y].conteins == "nofood") {
 +
  snake.body.push({x:next.x, y:next.y});
 +
  snake.head = {x:next.x, y:next.y};
 +
  field[next.x][next.y].conteins = "snake";
 +
  field[snake.body[0].x][snake.body[0].y].conteins = "empty";
 +
  snake.body.shift();
 +
  score++;
 +
  nofood=false;
 +
  }
 +
  if (field[next.x][next.y].conteins == "empty") {
 +
  snake.body.push({x:next.x, y:next.y});
 +
  snake.head = {x:next.x, y:next.y};
 +
  field[next.x][next.y].conteins = "snake";
 +
  field[snake.body[0].x][snake.body[0].y].conteins = "empty";
 +
  snake.body.shift();
 +
  }
 +
  } catch (err){
 +
  console.error("Что то пошло не так; X=", next.x, "Y=", next.y);
 +
  clearInterval(intervalID);
 +
  }
 +
  if (((score+1) % 5 == 0)&&(!nofood)){
 +
  CreateItem ('nofood');
 +
  nofood=true;
 +
  }
 +
  if (((score+1) % 8 == 0)&&(!nofoodno)){
 +
  CreateItem ('nofoodno');
 +
  nofoodno=true;
 +
  }
 +
}
 +
function control (){
 +
  if (!pause)
 +
  Calcul ();
 +
  if (!pause)
 +
  Draw();
 +
  CheckLength();
 +
}
 +
Init();
 +
Draw ();
 +
intervalID = setInterval(control, ms);
 +
}
 +
</syntaxhighlight>
 +
</div>

Текущая версия на 19:37, 19 июня 2019

Описание[править]

В этой игре пользователь управляет змейкой, которая ползает по плоскости, ограниченной стенками, и собирает еду, избегая столкновения с собственным хвостом и краями игрового поля.

Исполнители: Демина К.В., Прохоренкова И.Г., Малышева В.Н.

Группа 13632/1 Кафедра Теоретической механики.

Файл: Текст курсового проекта

Математическая модель[править]

Поле представляет собой прямоугольник, в пределах которого движется зеленая ячейка, являющаяся змейкой, и красные, синие и желтые ячейки, которые представляют собой еду для нее.

Визуализация[править]

Код программы[править]

  1  window.addEventListener("load",main,false);
  2  function main_code(){
  3  var ctx = SnakeS.getContext("2d");
  4  var h = SnakeS.height;
  5  var w = SnakeS.width;
  6  var n = 45;
  7  var intervalID;
  8  var direction = "left";
  9  var ms =200;
 10  var score = 0;
 11  var wCode = 87;
 12  var aCode = 65;
 13  var sCode = 83;
 14  var dCode = 68;
 15  var upCode = 38;
 16  var leftCode = 37;
 17  var downCode = 40;
 18  var rightCode = 39;
 19  var pause = false;
 20  function get_mouse_coords(e){ 
 21  var m = {};
 22  var rect = SnakeS.getBoundingClientRect();
 23  m.x = e.clientX - rect.left;
 24  m.y = e.clientY - rect.top;
 25  return m;
 26  }
 27  SnakeS.onclick = function(e){
 28   var m = get_mouse_coords(e);
 29   console.log(m.x, m.y);
 30   if ((m.x>(w/2-95))&&(m.x<(w/2+95))&&(m.y>(h/2+30))&&(m.y<(h/2+70))) {
 31    console.log(1);
 32    location.reload();
 33   }
 34  }
 35  var sl=1;
 36  var nofood = false;
 37  var nofoodno = false;
 38  var x = w/n;
 39  var y = h/n;
 40  console.log(x,y);
 41  function box(){
 42   this.conteins = "empty";		
 43  }
 44  function Snake(){
 45   this.head = null;
 46   this.tail = null;
 47   this.body = [];
 48   this.length = 1;
 49  }
 50  var field = [];
 51  for (var i=0; i<n; i++) {
 52   var m = [];
 53   for (var j=0; j<n; j++){
 54    m.push(new box());
 55   }
 56   field.push(m);
 57  }
 58  var snake = new Snake();
 59  function finish() {
 60   ctx.textAlign = 'center';
 61   ctx.font = '30px Georgia';
 62   pause = true;
 63   console.error("Вы проиграли");
 64   clearInterval(intervalID);
 65   ctx.fillStyle = 'rgb(180, 234, 255)';
 66   ctx.fillRect(0.25*w, 0.25*h, 0.5*w, 0.5*h);
 67   ctx.strokeStyle = 'black';
 68   ctx.strokeRect(0.25*w, 0.25*h, 0.5*w, 0.5*h);
 69   ctx.fillStyle = 'black';
 70   ctx.fillText('Вы проиграли!', w/2, h/2-40);
 71   ctx.fillText('Ваш счет: '+score, w/2, h/2);
 72   ctx.fillStyle = 'rgb(14, 151, 184)';
 73   ctx.fillRect(w/2-95, h/2+30, 190, 40);
 74   ctx.strokeRect(w/2-95, h/2+30, 190, 40);
 75   ctx.fillStyle = 'black';
 76   ctx.fillText('Сыграть еще', w/2, h/2+60);
 77   console.info('rtr');
 78  }
 79  function CreateItem(item){
 80   var i=Math.round(Math.random()*(n - 1));
 81   var j=Math.round(Math.random()*(n - 1));
 82   while (field [i][j].conteins != "empty"){
 83     var i=Math.round(Math.random()*(n - 1));
 84     var j=Math.round(Math.random()*(n - 1));
 85    }
 86   field [i][j].conteins = item;
 87  }
 88  function Init(){
 89    var i=Math.round(Math.random()*(n - 1));
 90    var j=Math.round(Math.random()*(n - 1));
 91    field [i][j].conteins = "food";
 92    var i=Math.round(Math.random()*(n - 1));
 93    var j=Math.round(Math.random()*(n - 1));
 94    while (field [i][j].conteins == "food"){
 95     var i=Math.round(Math.random()*(n - 1));
 96     var j=Math.round(Math.random()*(n - 1));
 97    }
 98    field [i][j].conteins = "snake";
 99    snake.head = {x: i, y: j};
100    snake.tail = {x: i, y: j};
101    snake.body.push({x: i, y: j}) ;
102    console.log(direction, snake.body, snake.head);
103    CreateItem('nofood');
104  }
105  function Draw() {
106   for (var i=0; i<n; i++) {
107    for (var j=0; j<n; j++){
108     if (field[i][j].conteins == "empty") {
109     ctx.fillStyle = 'white';
110     ctx.fillRect(x*i, y*j, x, y);
111     }
112     if (field[i][j].conteins == "food") {
113     ctx.fillStyle = 'red';
114     ctx.fillRect(x*i, y*j, x, y);
115     ctx.strokeStyle = 'black';
116     ctx.strokeRect(x*i, y*j, x, y);
117     }
118     if (field[i][j].conteins == "snake") {
119     ctx.fillStyle = 'green';
120     ctx.fillRect(x*i, y*j, x, y);
121     ctx.strokeStyle = 'black';
122     ctx.strokeRect(x*i, y*j, x, y);
123     }
124     if (field[i][j].conteins == "nofood") {
125     ctx.fillStyle = 'blue';
126     ctx.fillRect(x*i, y*j, x, y);
127     ctx.strokeStyle = 'black';
128     ctx.strokeRect(x*i, y*j, x, y);
129     }
130     if (field[i][j].conteins == "nofoodno") {
131     ctx.fillStyle = 'yellow';
132     ctx.fillRect(x*i, y*j, x, y);
133     ctx.strokeStyle = 'black';
134     ctx.strokeRect(x*i, y*j, x, y);
135     }
136    }
137   }
138   document.getElementById('scre').innerHTML = score;
139  }
140  window.onkeydown = function(evt) { 
141  evt = evt || window.event;
142  var charCode = evt.keyCode || evt.which;
143  console.log(charCode); 
144  if (((charCode == wCode)||(charCode == upCode)) && direction != "down") {
145   direction = "up";
146  }
147  if (((charCode == sCode)||(charCode == downCode)) && direction != "up") {
148   direction = "down"; 
149  }
150  if (((charCode == aCode)||(charCode == leftCode)) && direction != "right") {
151   direction = "left";
152  }
153  if (((charCode == dCode)||(charCode == rightCode)) && direction != "left") {
154   direction = "right";
155  }
156  }
157  function CheckLength() {
158   if ((score == 3) && (sl != 2)){
159    sl = 2;
160    ms = ms-100;
161    clearInterval(intervalID);
162    intervalID = setInterval(control, ms);
163    return ;
164   }
165   if ((score == 5 ) && (sl != 3)){
166    sl = 3;
167    ms = ms-50;
168    clearInterval(intervalID);
169    intervalID = setInterval(control, ms);
170   }
171  }
172  function Calcul(){
173   var next 
174   try {
175   if (direction == "left") {
176    next = {x: snake.head.x-1, y: snake.head.y}
177   }
178   if (direction == "right") {
179    next = {x: snake.head.x+1, y: snake.head.y}
180   }
181   if (direction == "up") {
182    next = {x: snake.head.x, y: snake.head.y-1}
183   }
184   if (direction == "down" && snake.length == 1) {
185    next = {x: snake.head.x, y: snake.head.y+1}
186   }
187   if (direction == "down" && snake.length > 1) {
188    next = {x: snake.head.x, y: snake.head.y}
189   }
190   if (score > 5) {
191    if (next.x<0) {
192     next.x = n-1
193     console.log('TP')
194     }
195    if (next.y<0) {
196     next.y = n-1
197     console.log('TP')
198     
199    if (next.x>n-1) {
200     next.x = 0
201     console.log('TP')
202     }
203    if (next.y>n-1) {
204     next.y = 0
205     console.log('TP')
206      }	
207   } else {
208    if (next.x<0) {
209     finish();
210     return;
211     }
212    if (next.y<0) {
213     finish();
214     return;
215     }
216    if (next.x>n-1) {
217     finish();
218     return;
219     }
220    if (next.y>n-1) {
221     finish();
222     return;
223     }	
224   }
225   if (field[next.x][next.y].conteins == "snake") {
226    finish();
227    return;
228   }
229   if (field[next.x][next.y].conteins == "food") {
230    snake.body.push({x:next.x, y:next.y});
231    snake.head = {x:next.x, y:next.y};
232    field[next.x][next.y].conteins = "snake";
233    CreateItem ('food');
234    score++;
235   }
236   if (field[next.x][next.y].conteins == "nofoodno") {
237    snake.body.push({x:next.x, y:next.y});
238    snake.head = {x:next.x, y:next.y};
239    field[next.x][next.y].conteins = "snake";
240    field[snake.body[0].x][snake.body[0].y].conteins = "empty";
241    snake.body.shift();
242    if(snake.body.length!=1)
243     field[snake.body[0].x][snake.body[0].y].conteins = "empty";
244     snake.body.shift();
245    score++;
246    nofoodno=false;
247   }
248   if (field[next.x][next.y].conteins == "nofood") {
249    snake.body.push({x:next.x, y:next.y});
250    snake.head = {x:next.x, y:next.y};
251    field[next.x][next.y].conteins = "snake";
252    field[snake.body[0].x][snake.body[0].y].conteins = "empty";
253    snake.body.shift();
254    score++;
255    nofood=false;
256   }
257   if (field[next.x][next.y].conteins == "empty") {
258    snake.body.push({x:next.x, y:next.y});
259    snake.head = {x:next.x, y:next.y};
260    field[next.x][next.y].conteins = "snake";
261    field[snake.body[0].x][snake.body[0].y].conteins = "empty";
262    snake.body.shift();
263   }
264   } catch (err){
265    console.error("Что то пошло не так; X=", next.x, "Y=", next.y);
266    clearInterval(intervalID);
267   }
268   if (((score+1) % 5 == 0)&&(!nofood)){
269    CreateItem ('nofood');
270    nofood=true;
271   }
272   if (((score+1) % 8 == 0)&&(!nofoodno)){
273    CreateItem ('nofoodno');
274    nofoodno=true;
275   }
276  }
277  function control (){
278   if (!pause)
279    Calcul ();
280   if (!pause)
281    Draw();
282   CheckLength();
283  }
284  Init();
285  Draw ();
286  intervalID = setInterval(control, ms);
287 }