parent
86c976584f
commit
998b9ee6aa
33 changed files with 605 additions and 34 deletions
@ -0,0 +1,25 @@ |
||||
package com.kob.backend.controller.pk; |
||||
|
||||
import com.kob.backend.controller.service.pk.ReceiveBotMoveService; |
||||
import org.springframework.beans.factory.annotation.Autowired; |
||||
import org.springframework.util.MultiValueMap; |
||||
import org.springframework.web.bind.annotation.PostMapping; |
||||
import org.springframework.web.bind.annotation.RequestParam; |
||||
import org.springframework.web.bind.annotation.RestController; |
||||
|
||||
import java.util.Objects; |
||||
|
||||
@RestController |
||||
public class ReceiveBotController { |
||||
@Autowired |
||||
private ReceiveBotMoveService receiveBotMoveService; |
||||
|
||||
@PostMapping("/pk/receive/bot/move/") |
||||
public String receiveBotMove(@RequestParam MultiValueMap<String,String> data){ |
||||
Integer userId = Integer.parseInt(Objects.requireNonNull(data.getFirst("user_id"))); |
||||
Integer direction = Integer.parseInt(Objects.requireNonNull(data.getFirst("direction"))); |
||||
|
||||
return receiveBotMoveService.receiveBotMove(userId,direction); |
||||
} |
||||
|
||||
} |
@ -0,0 +1,25 @@ |
||||
package com.kob.backend.controller.service.impl.pk; |
||||
|
||||
import com.kob.backend.consumer.WebSocketServer; |
||||
import com.kob.backend.consumer.utils.Game; |
||||
import com.kob.backend.controller.service.pk.ReceiveBotMoveService; |
||||
import org.springframework.stereotype.Service; |
||||
|
||||
@Service |
||||
public class ReceiveBotMoveServiceImpl implements ReceiveBotMoveService { |
||||
@Override |
||||
public String receiveBotMove(Integer userId, Integer direction) { |
||||
System.out.println("receive bot move: " + userId + " " + direction); |
||||
if (WebSocketServer.users.get(userId) != null) { |
||||
Game game = WebSocketServer.users.get(userId).game; |
||||
if (game != null) { |
||||
if (game.getPlayerA().getId().equals(userId)) { |
||||
game.setNextStepA(direction); |
||||
} else if (game.getPlayerB().getId().equals(userId)) { |
||||
game.setNextStepB(direction); |
||||
} |
||||
} |
||||
} |
||||
return "receive bot move success"; |
||||
} |
||||
} |
@ -0,0 +1,5 @@ |
||||
package com.kob.backend.controller.service.pk; |
||||
|
||||
public interface ReceiveBotMoveService { |
||||
String receiveBotMove(Integer userId,Integer direction); |
||||
} |
@ -0,0 +1,14 @@ |
||||
package com.kob.botRunningSystem; |
||||
|
||||
import com.kob.botRunningSystem.Service.BotRunningService; |
||||
import com.kob.botRunningSystem.Service.impl.BotRunningServiceImpl; |
||||
import org.springframework.boot.SpringApplication; |
||||
import org.springframework.boot.autoconfigure.SpringBootApplication; |
||||
|
||||
@SpringBootApplication |
||||
public class BotRunningSystemApplication { |
||||
public static void main(String[] args) { |
||||
BotRunningServiceImpl.botpool.start(); // 启动bot代码执行线程
|
||||
SpringApplication.run(BotRunningSystemApplication.class,args); |
||||
} |
||||
} |
@ -0,0 +1,24 @@ |
||||
package com.kob.botRunningSystem.Controller; |
||||
|
||||
import com.kob.botRunningSystem.Service.BotRunningService; |
||||
import org.springframework.beans.factory.annotation.Autowired; |
||||
import org.springframework.util.MultiValueMap; |
||||
import org.springframework.web.bind.annotation.PostMapping; |
||||
import org.springframework.web.bind.annotation.RequestParam; |
||||
import org.springframework.web.bind.annotation.RestController; |
||||
|
||||
import java.util.Objects; |
||||
|
||||
@RestController |
||||
public class BotRunningController { |
||||
@Autowired |
||||
private BotRunningService botRunningService; |
||||
@PostMapping("/bot/add/") |
||||
public String addBot(@RequestParam MultiValueMap<String,String> data){ |
||||
Integer userId = Integer.parseInt(Objects.requireNonNull(data.getFirst("user_id"))); |
||||
String botCode = data.getFirst("bot_code"); |
||||
String input = data.getFirst("input"); |
||||
|
||||
return botRunningService.addBot(userId,botCode,input); |
||||
} |
||||
} |
@ -0,0 +1,7 @@ |
||||
package com.kob.botRunningSystem.Service; |
||||
|
||||
|
||||
public interface BotRunningService { |
||||
String addBot(Integer userId,String botCode,String input); // 用户id,bot执行代码,一些输入信息(地图,位置,操作等)
|
||||
|
||||
} |
@ -0,0 +1,16 @@ |
||||
package com.kob.botRunningSystem.Service.impl; |
||||
|
||||
import com.kob.botRunningSystem.Service.BotRunningService; |
||||
import com.kob.botRunningSystem.Service.impl.utils.BotPool; |
||||
import org.springframework.stereotype.Service; |
||||
|
||||
@Service |
||||
public class BotRunningServiceImpl implements BotRunningService { |
||||
public static final BotPool botpool = new BotPool(); |
||||
@Override |
||||
public String addBot(Integer userId, String botCode, String input) { |
||||
System.out.println("add bot: " + userId + " " + botCode + " " + input); |
||||
botpool.addBot(userId,botCode,input); |
||||
return "add bot success"; |
||||
} |
||||
} |
@ -0,0 +1,14 @@ |
||||
package com.kob.botRunningSystem.Service.impl.utils; |
||||
|
||||
import lombok.AllArgsConstructor; |
||||
import lombok.Data; |
||||
import lombok.NoArgsConstructor; |
||||
|
||||
@Data |
||||
@NoArgsConstructor |
||||
@AllArgsConstructor |
||||
public class Bot { |
||||
Integer userId; |
||||
String botCode; |
||||
String input; |
||||
} |
@ -0,0 +1,48 @@ |
||||
package com.kob.botRunningSystem.Service.impl.utils; |
||||
|
||||
import java.util.LinkedList; |
||||
import java.util.Queue; |
||||
import java.util.concurrent.locks.Condition; |
||||
import java.util.concurrent.locks.ReentrantLock; |
||||
|
||||
public class BotPool extends Thread{ |
||||
private final ReentrantLock lock = new ReentrantLock(); // 加锁
|
||||
private final Condition condition = lock.newCondition(); // 条件变量
|
||||
private final Queue<Bot> bots = new LinkedList<>(); // 所有bots
|
||||
|
||||
|
||||
public void addBot(Integer userId,String botCode,String input) { |
||||
lock.lock(); |
||||
try { |
||||
bots.add(new Bot(userId,botCode,input)); // 添加一个bot
|
||||
condition.signalAll(); // 唤醒其他线程
|
||||
}finally { |
||||
lock.unlock(); |
||||
} |
||||
} |
||||
|
||||
|
||||
private void consume(Bot bot) { |
||||
Consumer consumer = new Consumer(); |
||||
consumer.setTimeout(2000,bot); |
||||
} |
||||
@Override |
||||
public void run() { |
||||
while (true) { |
||||
lock.lock(); |
||||
if (bots.isEmpty()) { |
||||
try { |
||||
condition.await(); |
||||
} catch (InterruptedException e) { |
||||
e.printStackTrace(); |
||||
lock.unlock(); |
||||
break; |
||||
} |
||||
} else { |
||||
Bot bot = bots.remove(); // 取出队头
|
||||
lock.unlock(); // 先解锁
|
||||
consume(bot); // 执行bot的代码(可能比较耗时)
|
||||
} |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,64 @@ |
||||
package com.kob.botRunningSystem.Service.impl.utils; |
||||
|
||||
import com.kob.botRunningSystem.utils.BotInterface; |
||||
import org.joor.Reflect; |
||||
import org.springframework.beans.factory.annotation.Autowired; |
||||
import org.springframework.stereotype.Component; |
||||
import org.springframework.util.LinkedMultiValueMap; |
||||
import org.springframework.util.MultiValueMap; |
||||
import org.springframework.web.client.RestTemplate; |
||||
import java.util.UUID; |
||||
|
||||
|
||||
@Component |
||||
public class Consumer extends Thread{ |
||||
|
||||
private Bot bot; |
||||
|
||||
private static RestTemplate restTemplate; |
||||
|
||||
private static final String receiveBotMoveUrl = "http://127.0.0.1:3000/pk/receive/bot/move/"; |
||||
|
||||
@Autowired |
||||
private void setRestTemplate(RestTemplate restTemplate) { |
||||
Consumer.restTemplate = restTemplate; |
||||
} |
||||
|
||||
public void setTimeout(long timeout,Bot bot) { |
||||
this.bot = bot; |
||||
this.start(); |
||||
try { |
||||
this.join(timeout); // 最多等待timeout秒
|
||||
} catch (InterruptedException e) { |
||||
e.printStackTrace(); |
||||
} finally { |
||||
this.interrupt(); // 终止当前进程
|
||||
} |
||||
} |
||||
|
||||
private String addUid(String code,String uid) { // 在Code的bot类名后添加uid
|
||||
int k = code.indexOf(" implements com.kob.botRunningSystem.utils.BotInterface"); |
||||
return code.substring(0,k) + uid + code.substring(k); |
||||
|
||||
} |
||||
|
||||
|
||||
@Override |
||||
public void run() { |
||||
|
||||
UUID uuid = UUID.randomUUID(); |
||||
String uid = uuid.toString().substring(0,8); // 获取8位随机字符串
|
||||
|
||||
BotInterface botInterface = Reflect.compile( |
||||
"com.kob.botRunningSystem.utils.Bot" + uid, |
||||
addUid(bot.getBotCode(),uid)).create().get(); |
||||
Integer direction = botInterface.nextMove(bot.getInput()); |
||||
System.out.println("move-direction: " + bot.getUserId() + " " + direction); |
||||
|
||||
MultiValueMap<String,String> data = new LinkedMultiValueMap<>(); |
||||
data.add("user_id",bot.getUserId().toString()); |
||||
data.add("direction",direction.toString()); |
||||
|
||||
restTemplate.postForObject(receiveBotMoveUrl,data,String.class); |
||||
} |
||||
} |
@ -0,0 +1,13 @@ |
||||
package com.kob.botRunningSystem.config; |
||||
|
||||
import org.springframework.context.annotation.Bean; |
||||
import org.springframework.context.annotation.Configuration; |
||||
import org.springframework.web.client.RestTemplate; |
||||
|
||||
@Configuration |
||||
public class RestTemplateConfig { |
||||
@Bean |
||||
public RestTemplate getRestTemplate() { |
||||
return new RestTemplate(); |
||||
} |
||||
} |
@ -0,0 +1,30 @@ |
||||
package com.kob.botRunningSystem.config; |
||||
|
||||
import org.springframework.context.annotation.Configuration; |
||||
import org.springframework.http.HttpMethod; |
||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity; |
||||
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; |
||||
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; |
||||
import org.springframework.security.config.http.SessionCreationPolicy; |
||||
|
||||
/** |
||||
* @author zfp |
||||
*/ |
||||
@Configuration |
||||
@EnableWebSecurity |
||||
public class SecurityConfig extends WebSecurityConfigurerAdapter { |
||||
|
||||
@Override |
||||
protected void configure(HttpSecurity http) throws Exception { |
||||
http.csrf().disable() |
||||
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS) |
||||
.and() |
||||
.authorizeRequests() |
||||
.antMatchers("/bot/add/").hasIpAddress("127.0.0.1") |
||||
.antMatchers(HttpMethod.OPTIONS).permitAll() |
||||
.anyRequest().authenticated(); |
||||
} |
||||
|
||||
|
||||
|
||||
} |
@ -0,0 +1,80 @@ |
||||
package com.kob.botRunningSystem.utils; |
||||
|
||||
import java.util.ArrayList; |
||||
import java.util.List; |
||||
|
||||
public class Bot implements com.kob.botRunningSystem.utils.BotInterface{ |
||||
static class Cell{ |
||||
public int x,y; |
||||
public Cell(int x,int y) { |
||||
this.x = x; |
||||
this.y = y; |
||||
} |
||||
} |
||||
|
||||
private boolean check_tail_increasing(int steps) { |
||||
if (steps <= 10) { |
||||
return true; |
||||
} |
||||
if (steps % 3 == 1) { |
||||
return true; |
||||
} |
||||
return false; |
||||
} |
||||
|
||||
public List<Cell> getCells(int sx,int sy,String steps) { |
||||
steps = steps.substring(1,steps.length() - 1); // 去掉编码时加的'()'
|
||||
List<Cell> res = new ArrayList<>(); |
||||
|
||||
int []dx = {-1,0,1,0}, dy = {0,1,0,-1}; |
||||
int x = sx, y = sy; |
||||
int step = 0; |
||||
res.add(new Cell(x,y)); |
||||
for (int i = 0; i < steps.length(); i++) { |
||||
int d = steps.charAt(i) - '0'; |
||||
x += dx[d]; |
||||
y += dy[d]; |
||||
res.add(new Cell(x,y)); |
||||
step++; |
||||
if (!check_tail_increasing(step)) { |
||||
res.remove(0); |
||||
} |
||||
} |
||||
return res; |
||||
} |
||||
|
||||
@Override |
||||
public Integer nextMove(String input) { |
||||
String[] strs = input.split("#"); |
||||
int [][] g = new int[13][14]; |
||||
for (int i = 0,k = 0; i < 13; i++) { |
||||
for (int j = 0; j < 14; j++,k++) { |
||||
if (strs[0].charAt(k) == '1') |
||||
g[i][j] = 1; |
||||
} |
||||
} |
||||
|
||||
int aSx = Integer.parseInt(strs[1]), aSy = Integer.parseInt(strs[2]); |
||||
int bSx = Integer.parseInt(strs[4]), bSy = Integer.parseInt(strs[5]); |
||||
|
||||
// 蛇的身体标记为1
|
||||
List<Cell> cellsA = getCells(aSx,aSy,strs[3]); |
||||
List<Cell> cellsB = getCells(bSx,bSy,strs[6]); |
||||
|
||||
|
||||
for (Cell c: cellsA) g[c.x][c.y] = 1; |
||||
for (Cell c: cellsB) g[c.x][c.y] = 1; |
||||
|
||||
int[] dx = {-1,0,1,0}; |
||||
int[] dy = {0,1,0,-1}; |
||||
for (int i = 0; i < 4; i++) { |
||||
// 蛇尾坐标,cellsA表示自己的那条蛇
|
||||
int x = cellsA.get(cellsA.size() - 1).x + dx[i]; |
||||
int y = cellsA.get(cellsA.size() - 1).y + dy[i]; |
||||
if (x >= 0 && x < 13 && y >= 0 && y < 14 && g[x][y] == 0) { |
||||
return i; // 可以走的位置
|
||||
} |
||||
} |
||||
return 0; // 向上走
|
||||
} |
||||
} |
@ -0,0 +1,5 @@ |
||||
package com.kob.botRunningSystem.utils; |
||||
|
||||
public interface BotInterface { |
||||
Integer nextMove(String input); // 下一步要走的方向是什么
|
||||
} |
@ -0,0 +1 @@ |
||||
server.port=3002 |
@ -1,6 +1,6 @@ |
||||
package com.kob.matchingsystem.service; |
||||
|
||||
public interface MatchingService { |
||||
String addPlayer(Integer userId, Integer rating); |
||||
String addPlayer(Integer userId, Integer rating,Integer botId); |
||||
String removePlayer(Integer userId); |
||||
} |
||||
|
@ -0,0 +1,22 @@ |
||||
<template> |
||||
<div class="show"> |
||||
<div class="snakeInfo" style="background-color: #4876ec;" v-if="$store.state.user.id == $store.state.pk.a_id">蓝方</div> |
||||
<div class="snakeInfo" style="background-color: #f94848;" v-if="$store.state.user.id == $store.state.pk.b_id">红方</div> |
||||
</div> |
||||
</template> |
||||
|
||||
<script> |
||||
</script> |
||||
|
||||
<style scoped> |
||||
.snakeInfo { |
||||
width: 50px; |
||||
height: 50px; |
||||
border-radius: 50%; |
||||
position: absolute; |
||||
top: 30vh; |
||||
left: 8vw; |
||||
text-align: center; |
||||
line-height: 50px; |
||||
} |
||||
</style> |
Loading…
Reference in new issue